Лабораторная работа №2 Тема: Обработка одномерных массивов




Скачать 195.48 Kb.
НазваниеЛабораторная работа №2 Тема: Обработка одномерных массивов
Дата публикации30.07.2013
Размер195.48 Kb.
ТипЛабораторная работа
zadocs.ru > Экономика > Лабораторная работа
Лабораторная работа № 1.2
Тема: Обработка одномерных массивов



Цель: изучить составной тип данных – массив, основные свойства компоненты StringGrid, PageControl. Написать и отладить программу с использованием одномерных массивов. Изучить основные возможности работы со стандартными компонентами среды С++Builder. Научиться работать с массивами. Составить алгоритм и написать программу для решения указанных задач. Описание и результаты занести в отчет.

Теоретические сведения


Массив – конечная последовательность данных одного типа. Массив – объект сложного типа, каждый элемент которого определяется именем (ID) и целочисленным значением индекса (номера), по которому к элементу массива производится доступ. Рассмотрим одномерные массивы.

Внимание! Индексы массивов в языке С/С++ начинаются с 0.

В программе одномерный массив декларируется следующим образом:

тип ID массива [размер];

где размер – указывает количество элементов в массиве. Размер массива может задаваться константой или константным выражением. Для использования массивов переменного размера существует отдельный механизм – динамическое выделение памяти.

Примеры декларации массивов:

int a[5];

double b[4] = {1.5, 2.5, 3.75};

в целочисленном массиве а первый элемент а[0], второй – а[1], …, пятый – а[4]. Для массива b, состоящего из действительных чисел, выполнена инициализация, причем элементы массива получат следующие значения: b[0]=1.5, b[1]=2.5, b[2]=3.75, b[3]=0.

В языке С/С++ не проверяется выход индекса за пределы массива. Корректность использования индексов элементов массива должен контролировать программист.

Примеры описания массивов:

const Nmax=10; – задание максимального значения;

typedef double mas1[Nmax*2]; – описание типа одномерного массива;

mas1 a; – декларация массива а типа mas1;

int ss[10]; – массив из десяти целых чисел.

Элементы массивов могут использоваться в выражениях так же, как и обычные переменные, например:

f = 2*a[3] + a[Ss[i] + 1]*3;

a[n] = 1 + sqrt(fabs(a[n–1]));
^

Условные операторы



Условный оператор if используется для разветвления процесса выполнения кода программы на два направления.

В языке Си имеется две разновидности условного оператора: простой и полный. Синтаксис простого оператора:

if (выражение) оператор;

выражение – логическое или арифметическое выражение, вычисляемое перед проверкой, и, если выражение истинно (не равно нулю), то выполняется оператор, иначе он игнорируется; оператор – простой или составной (блок) оператор языка Си. Если в случае истинности выражения необходимо выполнить несколько операторов (более одного), их необходимо заключить в фигурные скобки.

Структурная схема простого оператора приведена на рис. 6.1.


Примеры записи условного оператора if:

if (x > 0) x = 0;

if (i != 1) j++, s = 1; – используем операцию «запятая»;

if (i != 1) {

j++; s = 1; – последовательность операций (блок);

}

if (getch() != 27) k = 0; – если нажата любая клавиша кроме “Esc”.

if (!x) exit (1); или if (x == 0) exit(1);

if (i>0 && i
if (a++) b++; – необязательно в качестве выражения использовать логические выражения.

Синтаксис полного оператора условного выполнения:

if (выражение) оператор 1 ;

else оператор 2 ;

Если выражение не равно нулю (истина), то выполняется оператор 1, иначе – оператор 2. Операторы 1 и 2 могут быть простыми или составными (блоками).

Наличие символа «;» перед словом else в языке Си обязательно.

Структурная схема такого оператора приведена на рис. 2.2.


Примеры записи:

if (x > 0) j = k+10;

else m = i+10;

if ( x>0 && k!=0 ) {

j = x/k;

x += 10;

}

else m = k*i + 10;

Операторы 1 и 2 могут быть любыми операторами, в том числе и условными. Тогда, если есть вложенная последовательность операторов if else, то фраза else связывается с ближайшим к ней предыдущим if, не содержащим ветвь else. Например:

if (n > 0)

if(a > b) z = a;

else z = b;

Здесь ветвь else связана со вторым if (a > b). Если же необходимо связать фразу else с внешним if, то используются операторные скобки:

if(n > 0) {

if(a > b) z = a;

}

else z = b;

В следующей цепочке операторов if – else – if выражения просматриваются последовательно:

if (выражение 1) оператор 1;

else

if (выражение 2) оператор 2;

else

if (выражение 3) оператор 3;

else оператор 4 ;

Если какое-то выражение оказывается истинным, то выполняется относящийся к нему оператор и этим вся цепочка заканчивается. Каждый оператор может быть либо отдельным оператором, либо группой операторов в фигурных скобках. Оператор 4 будет выполняться только тогда, когда ни одно из проверяемых условий не подходит. Иногда при этом не нужно предпринимать никаких явных действий, тогда последний else может быть опущен или его можно использовать для контроля, чтобы зафиксировать «невозможное» условие (своеобразная экономия на проверке условий).

Пример:

if (x < 0) printf("\n X отрицательное \n");

else if(x==0) printf ("\n X равно нулю \n");

else printf("\n X положительное \n");

Замечание. Наиболее распространенной ошибкой при создании условных операторов является использование в выражении операции присваивания «=» вместо операции сравнения на равенство операндов «==» (два знака равно). Например, в следующем операторе синтаксической ошибки нет:

if (x = 5) a++;

но значение а будет увеличено на единицу независимо от значения переменной х, т.к. результатом операции присваивания х = 5 в круглых скобках является значение 50 – истина.

^

Оператор цикла с предусловием и коррекцией for



Общий вид оператора:

for (выражение 1; выражение 2; выражение 3)

код цикла;

где выражение 1 – инициализация счетчика (параметр цикла);

выражение 2 – условие продолжения счета;

выражение 3 – коррекция счетчика.

На рис. 7.2, а представлена схема работы цикла for, а на рис. 7.2, б – символ блок-схемы, использующийся для его обозначения.


Рис. 2.3. Схемы оператора цикла for:
а –
схема работы; б – блок-схема

Инициализация используется для присвоения счетчику (параметру цикла) начального значения.

Выражение 2 определяет условие выполнения цикла. Как и в предыдущих случаях, если его результат не нулевой («истина»), – то цикл выполняется, иначе – происходит выход из цикла.

Коррекция выполняется после каждой итерации цикла и служит для изменения параметра цикла.

Выражения 1, 2 и 3 могут отсутствовать (пустые выражения), но символы «;» опускать нельзя.

Например, для суммирования первых ^ N натуральных чисел можно записать такой код:

sum = 0;

for ( i = 1; i<=N; i++) sum+=i;

Заметим, что в выражении 1 переменную-счетчик можно декларировать. Например:

for (int i = 1; i<=N; i++)

Областью действия такой переменной будет код цикла.

Но в старых версиях компиляторов такие действия могут интерпретироваться иначе.

Цикл for эквивалентен последовательности инструкций:

выражение 1;

while (выражение 2) {

...

выражение 3;

}

а оператор for (; выражение 2; )

код цикла;

эквивалентен оператору while (выражение 2)

код цикла;

Если пропущено выражение 2, то цикл будет выполняться бесконечно, поскольку пустое условие всегда остается истинным. Бесконечный оператор: for ( ; ; ) код цикла;

эквивалентен оператору while (1) код цикла;

В заголовке оператора for может использоваться операция «запятая». Она позволяет включать в его выражения несколько операторов. Тогда рассмотренный пример суммирования первых N натуральных чисел можно записать в следующем виде:

for ( sum = 0 , i = 1; i<=N; sum+= i , i++) ;

Оператор for имеет следующие возможности:

– можно вести подсчет с помощью символов, а не только чисел:

for (ch = 'a'; ch <= 'z'; ch++) ... ;

– можно проверить выполнение некоторого произвольного условия:

for (n = 0; s[i] >= '0' && s[i] < '9'; i++) ... ;

или

for (n = 1; n*n*n <= 216; n++) ... ;

Первое выражение необязательно должно инициализировать переменную. Необходимо только помнить, что первое выражение вычисляется только один раз, перед тем как остальные части начнут выполняться.

for (printf(" вводить числа по порядку! \n"); num!=6;)

scanf("%d", & num);

printf(" последнее число – это то, что нужно. \n");

В этом фрагменте первое сообщение выводится на печать один раз, а затем осуществляется прием вводимых чисел, пока не поступит число 6.

Переменные, входящие в выражения 2 и 3, можно изменять при выполнении кода цикла, например, значения k и delta:

for (n = 1; n < 10*k; n += delta) ... ;

Использование условных выражений позволяет во многих случаях значительно упростить программу, например:

for (i = 0; i
printf("%6d%c", a[i],( (i%10==0) || (i==n–1) ) ? '\n' : ′ ′);

В этом цикле печатаются n элементов массива а по 10 в строке, разделяя каждый столбец одним пробелом и заканчивая каждую строку (включая последнюю) одним символом перевода строки. Символ перевода строки записывается после каждого десятого и n-го элементов. За всеми остальными – пробел.

Наиболее часто встречающиеся ошибки при создании циклов – это использование в коде цикла неинициализированных переменных и неверная запись условия выхода из цикла.

Чтобы избежать ошибок, нужно стараться:

– проверить, всем ли переменным, встречающимся в правой части операторов присваивания в коде цикла, присвоены до этого начальные значения (а также возможно ли выполнение других операторов);

– проверить, изменяется ли в цикле хотя бы одна переменная, входящая в условие выхода из цикла;

– предусмотреть аварийный выход из цикла по достижении некоторого количества итераций;

– если в состав цикла входит не один, а несколько операторов, нужно заключать их в фигурные скобки.


^

Создание оконного приложения, используемые компоненты



Диалог с вкладками (компонент Page Control)


Для диалога со вкладками используется компонент Page Control со вкладки Win32:



Разместите его на форме. Для добавления вкладок на наш компонент просто щелкните на нем правой кнопкой мыши из контекстного меню выберите New Page. Таким способом можно добавить требуемое число вкладок. Удаляются они аналогично - из контекстного меню нужной вкладки выбираем Delete Page (для того, чтобы выделить нужную вкладку, просто щелкните на ней (но не на ее ярлычке - в этом случае выделится весь Page Control)).

После того, как вы добавите пару-тройку вкладок, они появятся в окне Object TreeView, так что для задания свойств конкретной вкладки просто щелкните на соответствующей стороке в окне Object TreeView:



Теперь можно размещать на вкладках разные элементы управления (как и на обычной форме).

^

Компонента StringGrid


При работе с массивами ввод и вывод значений обычно организуется с использованием компоненты StringGrid, предназначенной для отображения информации в виде двухмерной таблицы, каждая ячейка которой представляет собой окно однострочного редактора (аналогично окну Edit). Доступ к информации осуществляется с помощью элемента Cells[ACol][ARow] типа AnsiString, где целочисленные значения ACol, ARow указывают позицию элемента.

Внимание! Первый индекс ACol определяет номер столбца, а второй ARow – номер строки в отличие от индексов массива.

В инспекторе объектов значения ColCount и RowCount устанавливают начальные значения количества столбцов и строк в таблице, а FixedCols и FixedRows задают количество столбцов и строк фиксированной зоны. Фиксированная зона выделена другим цветом и обычно используется для надписей.

StringGrid


Компонент StringGrid представляет собой таблицу, ячейки которой содержат строки символов. Свойства компонента StringGrid приведены в табл.1.



Компонент StringGrid


Таблица 1. Свойства компонента StringGrid


Свойство


Описание


Name


Имя компонента. Используется в программе для доступа к компоненту и его свойствам


ColCount


Количество колонок таблицы


RowCount


Количество строк таблицы


DefaultColWidth


Ширина колонок таблицы


DefaultRowHeight


Высота строк таблицы


FixedCols


Количество зафиксированных слева колонок таблицы. Зафиксированные колонки выделяются цветом и при горизонтальной прокрутке таблицы остаются на месте


FixedRows


Количество зафиксированных сверху строк таблицы. Зафиксированные строки выделяются цветом и при вертикальной прокрутке таблицы остаются на месте


Cells


Соответствующий таблице двумерный массив. Ячейке таблицы, находящейся на пересечении столбца с номером col и строки с номером row, соответствует элемент cells [col] [row]


GridLineWidth


Ширина линий, ограничивающих ячейки таблицы


Left


Расстояние от левой границы поля таблицы до левой границы формы


Top


Расстояние от верхней границы поля таблицы до верхней границы формы


Height


Высота поля таблицы


Width


Ширина поля таблицы


Options . goEditing


Признак допустимости редактирования содержимого ячеек таблицы (true— редактирование разрешено, false — запрещено)


Options . goTab


Разрешает (true) или запрещает (false) использование клавиши <Таb> для перемещения курсора в следующую ячейку таблицы


Options.goAlwaysShowEditor


Признак нахождения компонента в режиме редактирования. Если значение свойства false, то для того чтобы в ячейке появился курсор, надо или начать набирать текст или нажать клавишу , или сделать щелчок мышью в ячейке таблицы


Font


Шрифт, используемый для отображения содержимого ячеек таблицы


ParentFont


Признак наследования характеристик шрифта формы

Edit


Компонент Edit (рис. П.2) представляет собой поле ввода-редактирования строки символов. Свойства компонента приведены в табл. П.3.



Рис. П.2. Компонент Edit — поле ввода-редактирования строки символов


Таблица П.3. Свойства компонента Edit (поле редактирования)


Свойство


Описание


Name


Имя компонента. Используется в программе для доступа к компоненту и его свойствам, в частности для доступа к тексту, введенному в поле редактирования


Text


Текст, находящийся в поле ввода и редактирования


Left


Расстояние от левой границы компонента до левой границы формы


Top


Расстояние от верхней границы компонента до верхней границы формы


Height


Высота поля


Width


Ширина поля


Font


Шрифт, используемый для отображения вводимого текста


ParentFont


Признак наследования компонентом характеристик шрифта формы, на которой находится компонент. Если значение свойства равно true, то при изменении свойства Font формы автоматически меняется значение свойства Font компонента


Enabled


Используется для ограничения возможности изменить текст в поле редактирования. Если значение свойства равно false, то текст в поле редактирования изменить нельзя


Visible


Позволяет скрыть компонент (false) или сделать его видимым (true)

Label


Компонент Label (рис. П.1) предназначен для вывода текста на поверхность формы. Свойства компонента (табл. П.2) определяют вид и расположение текста.



Рис. П.1. Компонент Label — поле вывода текста


Таблица П.2. Свойства компонента Label (поле вывода текста)


Свойство


Описание


Name


Имя компонента. Используется в программе для доступа к компоненту и его свойствам


Caption


Отображаемый текст


Left


Расстояние от левой границы поля вывода до левой границы формы


Top


Расстояние от верхней границы поля вывода до верхней границы формы


Height


Высота поля вывода


Width


Ширина поля вывода


AutoSize


Признак того, что размер поля определяется его содержимым


Wordwrap


Признак того, что слова, которые не помещаются в текущей строке, автоматически переносятся на следующую строку (значение свойства AutoSize должно быть false)


Alignment


Задает способ выравнивания текста внутри поля. Текст может быть выровнен по левому краю (taLeftJustify), по центру (taCenter) или по правому краю (taRight Justify)


Font


Шрифт, используемый для отображения текста. Уточняющие свойства определяют шрифт (Name), размер (size), стиль (style) и цвет символов (Color)


Parent Font


Признак наследования компонентом характеристик шрифта формы, на которой находится компонент. Если значение свойства равно true, то текст выводится шрифтом, установленным для формы


Color


Цвет фона области вывода текста


Transparent


Управляет отображением фона области вывода текста. Значение true делает область вывода текста прозрачной (область вывода не закрашивается цветом, заданным свойством Color)


Visible


Позволяет скрыть текст (false) или сделать его видимым (true)

Button


Компонент Button (рис. П.3) представляет собой командную кнопку. Свойства компонента приведены в табл. П.4.



Рис. П.3. Компонент Button — командная кнопка


Таблица П.4. Свойства компонента Button (командная кнопка)


Свойство


Описание


Name


Имя компонента. Используется в программе для доступа к компоненту и его свойствам


Caption


Текст на кнопке


Left


Расстояние от левой границы кнопки до левой границы формы


Top


Расстояние от верхней границы кнопки до верхней границы формы


Height


Высота кнопки


Width


Ширина кнопки


Enabled


Признак доступности кнопки. Если значение свойства равно true, то кнопка доступна. Если значение свойства равно false, то кнопка недоступна— например, в результате щелчка на кнопке, событие Click не возникает


Visible


Позволяет скрыть кнопку (false) или сделать ее видимой (true)


Hint


Подсказка— текст, который появляется рядом с указателем мыши при позиционировании указателя на командной кнопке (для того чтобы текст появился, надо, чтобы значение свойства ShowHint было true)


ShowHint


Разрешает (true) или запрещает (false) отображение подсказки при позиционировании указателя на кнопке



Перед написанием программы, продумать способ решения и составить алгоритм.
^

Пример создания приложения с одномерным массивом. Написание программы.



Задание: 1.Переставить элементы массива «зеркальным» способом.

2. Переставить пары рядом стоящих элементов

3. Переставить местами минимальный и максимальный элементы.
Выполнение.
1. Начнем с разработки интерфейса пользователя, т.е. с создания формы с объектами на ней. Запустить Builder. Открыть проект из лабораторной работы №1 (File ->Open).

  1. Сделать заголовком проекта свою фамилию. Для этого в Инспекторе объектов ввести свою фамилию в поле Caption для формы Form1.

  2. На форме создать две страницы с помощью компоненты Page Control, которая находится на панели Win32. Назвать их «Квадратное уравнение» и «1-мерный массив»

  3. На странице «1-мерный массив» создать, с помощью компонент Edit, Label Button интерфейс пользователя для ввода и вывода всех необходимых данных и результатов: окно для ввода/вывода массива, окно для вывода результата и кнопки для выполнения поставленных заданий.




  1. Все окна и события назвать именами, показывающими их предназначение.




  1. При двойном щелчке на кнопку, автоматически появляется Unit1.cpp форма, в которой необходимо написать программу для выполнения конкретного задания. Это заготовка для функции, которая будет запускаться при нажатии кнопки. Она имеет заголовок



#include

#pragma hdrstop

#include "Unit1.h"

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

int a[10], i,j, D, E, F;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){}

//---------------------------------------------------------------------------

void __fastcall TForm1::btOkClick(TObject *Sender)

{

int Max; //Поиск максимального элемента

Max=a[0];

for(i=0; i<10; i++)

{

if(a[i] > Max) Max = a[i];

}

edMax->Text = IntToStr(Max);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::btAvtoClick(TObject *Sender)

{

for(int i=0; i<10; i++)

{sgT->Cells[i][0] = IntToStr(rand() % 100); //Автозаполнение

a[i] = StrToInt(sgT->Cells[i][0]);}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::btAuto2Click(TObject *Sender)

{

for(int i=0; i<5; i++)

for(int j=0; j<5; j++)

sgT2->Cells[i][j] = IntToStr((rand() % 100) - 50);

void __fastcall TForm1::Button3Click(TObject *Sender)

{

for(i=0;i<10;i+=2)

{

E=a[i]; //Переставляем эл-ты с чет. и нечет.

a[i]=a[i+1]; //индексами

a[i+1]=E;

}
for(i=0; i<10; i++)

sgT->Cells[i][0]= IntToStr(a[i]);
}


}

  1. Программа готова. Запускаем для нее компиляцию.

  2. Отлаживаем, исправляем ошибки.

  3. Закрыть проект.

  4. Закрыть систему Builder.


Отчет по лабораторной работе должен включать:

  • теоретические сведения;

  • блок-схемы алгоритмов всех функций;

  • тексты программ с подробными комментариями;

  • выводы по проделанным экспериментам;

  • ответы на вопросы.
^

Индивидуальные задания


Написать программу по обработке одномерных массивов. Размеры массивов вводить с клавиатуры. В консольном приложении предусмотреть возможность ввода данных как с клавиатуры, так и с использованием функции random().

При создании оконного приложения скалярный (простой) результат выводить в виде компоненты Label, а массивы вводить и выводить с помощью компонент StringGrid.

В одномерном массиве, состоящем из n вводимых с клавиатуры целых элементов, вычислить:

  1. Произведение элементов массива, расположенных между максимальным и минимальным элементами.

  2. Сумму элементов массива, расположенных между первым и последним нулевыми элементами.

  3. Сумму элементов массива, расположенных до последнего положительного элемента.

  4. Сумму элементов массива, расположенных между первым и последним положительными элементами.

  5. Произведение элементов массива, расположенных между первым и вторым нулевыми элементами.

  6. Сумму элементов массива, расположенных между первым и вторым отрицательными элементами.

  7. Сумму элементов массива, расположенных до минимального элемента.

  8. Сумму модулей элементов массива, расположенных после последнего отрицательного элемента.

  9. Сумму элементов массива, расположенных после последнего элемента, равного нулю.

  10. Сумму модулей элементов массива, расположенных после минимального по модулю элемента.

  11. Сумму элементов массива, расположенных после минимального элемента.

  12. Сумму элементов массива, расположенных после первого положительного элемента.

  13. Сумму модулей элементов массива, расположенных после первого отрицательного элемента.

  14. Сумму модулей элементов массива, расположенных после первого элемента, рав­ного нулю.

  15. Сумму положительных элементов массива, расположенных до максимального элемента.

  16. Произведение элементов массива, расположенных между первым и последним отрицательными элементами.

  17. Сформировать новый массив С(40), элементами которого являются суммы и разности соответствующих элементов исходных массивов.


Вопросы

1 Какие типы данных существуют в языке С++ Builder?

2. Организация проекта в С++ Builder, основные файлы проекта.

3. Дать определение массива?

4. Каким образом задается массив и выводится на экран?
5. Нормативы построения алгоритмов.

7. Палитра компонентов. Что такое компоненты и их свойства?

8. Окно Object Treе View и страница диаграмм Редактора Кода.

9. Создание и сохранение проекта, приложения, форм.

10. Что такое модульный принцип программирования?

Добавить документ в свой блог или на сайт

Похожие:

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа 5 тема: Первичная обработка рыбы и рыбного сырья
...

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа № Работа с массивами и записями
Получить представление о том, что такое массив и научиться разрабатывать алгоритмы решения задач с использованием массивов в среде...

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа № Лабораторная работа №3 Тема: «Работа с панелью...
Основные приемы работы(контекстное меню, выделение, группирование объектов, перетаскивание мышью, получение справки)

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа по теме «Тема 10. Лабораторная работа «Текстовые файлы»
Цель лабораторной работы состоит в изучении средств vb и средств vs для работы с текстовыми файлами

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа №2 По теме: “Обработка графической информации в программе
По теме: “Обработка графической информации в программе Photoshop c использованием инструмента «кисть» ”

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа №2 Тема: «Работа с таблицами и формулами» Тема:...
Способы создания простой и сложной таблиц( разбиение, объединение ячеек, добавление и удаление ячеек, строк, столбцов)

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа №5. Генерация отчетов в субд access лабораторная...
Лабораторная работа №3. Изменения экранного образа таблицы в субд access лабораторная работа №4. Простые и сложные запросы к базе...

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа по Microsoft Excel №4 Тема: Управление листами. Работа со списками
В поле Перед листом выберите лист, перед которым нужно вставить перемещаемые или копируемые листы

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа выполняется по темам: «Оптимизационные экономико-математические...
Лабораторная работа выполняется и защищается в соответствии с утвержденным расписанием занятий

Лабораторная работа №2 Тема: Обработка одномерных массивов iconЛабораторная работа 3 (2003). Тема : Работа с буфером обмена. Создание...
Тема: Работа с буфером обмена. Создание списков. Работа с изображениями в текстовых документах

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
zadocs.ru
Главная страница

Разработка сайта — Веб студия Адаманов