Основные теоретические положения
Определение массивов
Массив (array) – это тип данных, предоставляющий набор однородных значений, доступ к которым осуществляется с помощью индексов (индексированный набор однотипных данных). В языке С++ допустимы массивы любых типов – массивы скалярных значений, массивы указателей, массивы структур, массивы объектов, массивы массивов.
Объявление массива имеет префиксную форму и в общем виде может быть представлено так:
тип имя_массива [размер]; // вектор
тип имя_массива [размер_1][размер_2]; // матрица
Доступ к элементу массива осуществляется через его имя и значение индекса, приведенное в квадратных скобках:
имя_массива [выражение]
имя_массива [выражение_1][выражение_2],
Здесь выражение – это выражение целого типа, значение которого должно быть в диапазоне от 0 до (размер – 1). Компилятор не выполняет строгую проверку выхода индекса за границы диапазона.
Примеры объявления массивов:
int m[10]; // массив-вектор из 10 целых, доступ – m[i], i = 0 ÷ 9
float mm[3][4]; //массив-матрица из 3 ´ 4 вещественных, доступ mm[i][j], i = 0÷2, j = 0÷3
char *d[3]; //массив из 3 указателей на char (строк), доступ d[i], i = 0÷2
Массив может быть инициализирован при объявлении:
int m[10] = {9,8,7,6,5,4,3,2,1,0};
float mm[3][4] = {{0.1,0.2,0.3,0.4},{1.1,1.2,1.3,1.4},{2.1,2.2,2.3,2.4}};
char *d[] = {«С++», «Паскаль», «Ада»}; // размер соответствует количеству // инициализаторов
Массивы и указатели
Имя массива является базовым (начальным) адресом в памяти, где хранится массив, это адрес элемента массива с индексом 0: m = &m[0]. В этой связи доступ к памяти для массивов и указателей ничем не отличается:
int m[10], *p = m; //p = &m[0]
for (int i = 0 ; i < 10; i++)
m[i] = i; // p[i] = i;
Выражения вида: m[i], mm[i][j] соответствуют выражениям более низкого уровня: *(m + i), *(*(mm + i) + j).
Имя массива-матрицы mm является базовым адресом одномерного массива указателей (mm[i] – адрес i-й строки), каждый элемент которого – также одномерный массив.
Например, массив int mm[N][M] может быть сформирован на базе массива int *mm[N] при выделении для каждого элемента (mm[i]) памяти для хранения M целых чисел или на базе указателя int **mm при выделении сначала памяти для хранения N указателей на int, а затем для хранения M целых по каждому из N указателей.
Передача массивов функциям
Для обработки массива функций базовый адрес массива передается по значению, содержимое массива при этом не копируется.
П р и м е р: определение функции
int summa (const int m[], int s) // m – указатель, m = massiv, s – размер, s = size
{ int i, sum = 0;
for (i = 0; i < s; i++)
sum+ = m[i];
return sum;
}
вызов функции
y = summa(massiv, size); // massiv – имя массива, size – размер
Наличие const в объявлении формального параметра m не позволит функции изменить содержимое массива.
Массивы-строки
Тип char* или char[] является формой строкового типа при условии, что последовательность символов заканчивается нулевым символом – ‘\0’. Только в этом случае функции из типа string или string.h могут обрабатывать строки. В библиотеке string (ANSI C++) реализован шаблонный класс string, который может использоваться как стандартизованный строковый тип. При этом необходимо подключить пространство имен стандартных библиотек: using namespace std;
П р и м е р : char *s1 = ”C++”; // объявление и инициализация
сhar s2[] = {‘C++’,’+’,’+’,’\0’}; //инициализация
string s3 = ”C++”; // строк
Операторы управления свободной памятью
Для создания и уничтожения объектов применяются операторы new и delete, которые отвечают за выделение и освобождение свободной памяти. Это необходимо при работе с динамическими структурами данных такими, как векторы, матрицы, списки, деревья.
В общем виде операторы new и delete принимают следующие формы:
new имя_типа
new имя_типа (инициализатор)
new имя_типа [выражение]
delete выражение
delete [] выражение
П р и м е р : int *p, *m; // объявление p и m
p = new int(10); // выделение памяти и инициализация
m=new int[10]; // выделение памяти для массива из 10 целых
delete p; // освобождение памяти
delete []m; // освобождение памяти
Задания
1. Сформировать случайным образом два массива, расположив их, соответственно, в статической и динамической памяти; тип массива: 1) «вектор»; 2) «матрица»; 3) «куб».
2. Реализовать функцию обработки массива для следующих вариантов:
1) вычислить сумму и число положительных элементов вектора (каждой строки матрицы, каждой матрицы куба);
2) найти два максимальных элемента;
3) выполнить сортировку по возрастанию;
4) вычислить произведение положительных элементов вектора (матрицы, куба);
5) вычислить среднее арифметическое суммы элементов вектора (матрицы, куба);
6) если элемент вектора (матрицы, куба) £ 10, то вычислить произведение этих элементов, иначе вычислить сумму;
7) переставить элементы вектора (строк матрицы, матриц куба): 1 « N, 2 « N-1 и т.д.;
8) найти произведение первых трех элементов вектора (элементов третьего столбца матрицы, элементов третьей матрицы куба);
9) вычислить сумму последних трех положительных элементов вектора (элементов третьей строки матрицы, элементов третьей снизу матрицы куба);
10) выполнить сортировку по убыванию;
11) найти число элементов вектора (матрицы, куба), кратных пяти;
12) записать в вектор (матрицу, куб) на место отрицательных элементов нули, а на место положительных элементов – единицы;
13) найти два минимальных элемента;
14) найти сумму четных элементов вектора (элементов каждой четной строки матрицы, элементов четных матриц куба);
15) если элементы вектора (матрицы, куба) кратны двум, то вычислить произведение этих элементов, вычислить сумму оставшихся элементов;
16) найти сумму нечетных элементов вектора (элементов каждой нечетной строки матрицы, элементов нечетных матриц куба);
17) найти число элементов вектора (матрицы, куба), кратных трем;
18) вычислить сумму первых двух положительных элементов вектора (элементов второй строки матрицы, элементов второй матрицы куба);
19) вычислить сумму положительных элементов вектора (матрицы, куба) и вывести на экран индексы этих элементов;
20) найти квадраты элементов вектора (матрицы, куба) и вывести на экран новый вектор (матрицу, куб).
Проверьте работоспособность программы на тестовом наборе данных.
Контрольные вопросы
1. Что такое массив? Сформулируйте правила индексирования и инициализации массива.
2. Каким образом создается динамический массив? В чем различия между указателями массивов?
3. Опишите механизм передачи массива функциям.
4. Покажите взаимосвязь между массивами, указателями и ссылками.
5. Что означает «выход за границы массива», к чему это может привести?
6. В чем заключаются особенности работы со строками?
7. Каким образом осуществляется управление свободной памятью?
Раздел III