Глава 7 массивы
В повседневной жизни постоянно приходится сталкиваться с однотипными объектами. Как и многие другие языки высокого уровня, C++ предоставляет программисту возможность работы с наборами однотипных данных — массивами. Отдельная единица таких данных, входящих в массив, называется элементом массива. В качестве элементов массива могут выступать данные любого типа (один тип данных для каждого массива), а также указатели на однотипные данные. Массивы бывают одномерными и многомерными.
Поскольку все элементы массива имеют один тип, они также обладают одинаковым размером. Использованию массива в программе предшествует его объявление, резервирующее под массив определенное количество памяти. При этом указывается тип элементов массива, имя массива и его размер. Размер сообщает компилятору, какое количество элементов будет размещено в массиве. Например:
int Array[20];
зарезервирует в памяти место для размещения двадцати целочисленных элементов.
Элементы массива в памяти располагаются непосредственно один за другим. На рис. 6.1 показано расположение одномерного массива двухбайтных элементов (типа short) в памяти.
Обращение к элементам массива может осуществляться одним из двух способов:
• по номеру элемента в массиве (через его индекс);
• по указателю.
При обращении через индекс за именем массива в квадратных скобках указывается номер элемента, к которому требуется выполнить доступ. Следует помнить, что в C++ элементы массива нумеруются начиная с 0, Первый элемент массива имеет индекс 0, второй - индекс 1 и т.д. Таким образом, запись типа:
х = Аггау[13];
у = Аггау[19];
выполнит присвоение переменной х значения 14-го элемента, а переменной у - значение 20-го элемента массива.
Рис. 6.1. Одномерный массив в памяти
Доступ к элементам массива через указатели заключается в следующем. Имя объявляемого массива ассоциируется компилятором с адресом его самого первого элемента (с индексом 0). Таким образом, можно присвоить указателю адрес нулевого элемента, используя имя массива:
char ArrayOfChar[] = {'W,'О','R','L','D'};
char* pArr = ArrayOfChar;
Разыменовывая указатель pArr, можно получить доступ к содержимому ArrayOfChar[0]:
char Letter = *pArr;
Поскольку в C++ указатели и массивы тесно взаимосвязаны, увеличивая или уменьшая значение указателя на массив, программист получает возможность доступа ко всем элементам массива путем соответствующей модификации указателя:
// pArr указывает на ArrayOfChar[0] ('W') pArr += 3;
// pArr указывает на ArrayOfChar[3] ('L')
pArr++;
// pArr указывает на ArrayOfChar[4] ('D')
char Letter = *pArr; // Letter = 'D';
Таким образом, после проведенных арифметических операций указатель pArr будет ссылаться на элемент массива с индексом 4. К этому же элементу можно обратиться иным способом:
Letter = *(ArrayOfChar + 4);
// Эквивалент Letter = ArrayOfChar[4];
Присвоение значений одного массива значениям другого массива вида Array [ ] = Another [ ] или Array = Another недопустимо, так как компилятор не может самостоятельно скопировать все значения одного массива в значения другого. Для этого программисту необходимо предпринимать определенные действия (при доступе к элементам по индексу чаще всего используется циклическое присвоение). Объявление вида
char (*Array)[10];
определяет указатель Array на массив из 10 символов (char). Если же опустить скобки, компилятор поймет запись как объявление массива из 10 указателей на тип char. Рассмотрим пример использования массива.
#include <iostream.h>
int main () {
// Объявление целочисленного массива,
// содержащего 5 элементов:
short Number[5];
char endl = '\n';
// Заполнение всех элементов массива // в цикле
for(int i=0; i<5; i++) Number[i] = i;
//
// ...
//
// Вывод содержимого с 3-го
// по 5-й элемента for(int i=2; i<5; i++)
cout « Number[i] « endl;
return 0;
}