Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ для начинающих (Стенли Липпман) 3-е хххх.pdf
Скачиваний:
86
Добавлен:
30.05.2015
Размер:
5.92 Mб
Скачать

С++ для начинающих

111

void mumble() {

Points pt3d = point3d; // правильно: pt2d == 3

//ошибка: pt3w инициализируется типом int Points pt3w = 3;

//ошибка: polygon не входит в перечисление Points pt3w = polygon;

//правильно: оба объекта типа Points

pt3w = pt3d;

}

Однако в арифметических выражениях перечисление может быть автоматически

const int array_size = 1024;

// правильно: pt2w преобразуется int

преобразовано в тип int. Например:

int chunk_size = array_size * pt2w;

3.9. Тип массив

Мы уже касались массивов в разделе 2.1. Массив это набор элементов одного типа, доступ к которым производится по индексу порядковому номеру элемента в массиве. Например:

int ival;

определяет ival как переменную типа int, а инструкция

int ia[ 10 ];

задает массив из десяти объектов типа int. К каждому из этих объектов, или элементов массива, можно обратиться с помощью операции взятия индекса:

ival = ia[ 2 ];

присваивает переменной ival значение элемента массива ia с индексом 2. Аналогично

ia[ 7 ] = ival;

присваивает элементу с индексом 7 значение ival.

Определение массива состоит из спецификатора типа, имени массива и размера. Размер задает количество элементов массива (не менее 1) и заключается в квадратные скобки. Размер массива нужно знать уже на этапе компиляции, а следовательно, он должен быть константным выражением, хотя не обязательно задается литералом. Вот примеры правильных и неправильных определений массивов:

С++ для начинающих

112

extern int get_size();

// buf_size и max_files константы

const int buf_size = 512, max_files = 20; int staff_size = 27;

// правильно: константа

char input_buffer[ buf_size ];

// правильно: константное выражение: 20 - 3 char *fileTable[ max_files-3 ];

// ошибка: не константа double salaries[ staff_size ];

// ошибка: не константное выражение

int test_scores[ get_size() ];

Объекты buf_size и max_files являются константами, поэтому определения массивов input_buffer и fileTable правильны. А вот staff_size переменная (хотя и инициализированная константой 27), значит, salaries[staff_size] недопустимо. (Компилятор не в состоянии найти значение переменной staff_size в момент определения массива salaries.)

Выражение max_files-3 может быть вычислено на этапе компиляции, следовательно, определение массива fileTable[max_files-3] синтаксически правильно.

Нумерация элементов начинается с 0, поэтому для массива из 10 элементов правильным диапазоном индексов является не 1 – 10, а 0 – 9. Вот пример перебора всех элементов

int main()

{

const int array_size = 10; int ia[ array_size ];

for ( int ix = 0; ix < array_size; ++ ix ) ia[ ix ] = ix;

массива:

}

При определении массив можно явно инициализировать, перечислив значения его

const int array_size = 3;

элементов в фигурных скобках, через запятую: int ia[ array_size ] = { 0, 1, 2 };

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

// массив размера 3

компилятор сам подсчитает количество элементов: int ia[] = { 0, 1, 2 };

С++ для начинающих

113

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

// ia ==> { 0, 1, 2, 0, 0 } const int array_size = 5;

в списке больше значений, компилятор выводит сообщение об ошибке: int ia[ array_size ] = { 0, 1, 2 };

Символьный массив может быть инициализирован не только списком символьных значений в фигурных скобках, но и строковым литералом. Однако между этими

const char cal[] = {'C', '+', '+' };

способами есть некоторая разница. Допустим, const char cal2[] = "C++";

Размерность массива ca1 равна 3, массива ca2 – 4 (в строковых литералах учитывается

// ошибка: строка "Daniel" состоит из 7 элементов

завершающий нулевой символ). Следующее определение вызовет ошибку компиляции: const char ch3[ 6 ] = "Daniel";

Массиву не может быть присвоено значение другого массива, недопустима и инициализация одного массива другим. Кроме того, не разрешается использовать массив

const int array_size = 3; int ix, jx, kx;

//правильно: массив указателей типа int* int *iar [] = { &ix, &jx, &kx };

//error: массивы ссылок недопустимы

int &iar[] = { ix, jx, kx };

int main()

{

int ia3{ array_size ]; // правильно

// ошибка: встроенные массивы нельзя копировать

ia3 = ia; return 0;

ссылок. Вот примеры правильного и неправильного употребления массивов:

}

Чтобы скопировать один массив в другой, придется проделать это для каждого элемента по отдельности:

С++ для начинающих

114

const int array_size = 7;

int ia1[] = { 0, 1, 2, 3, 4, 5, 6 };

int main()

{

int ia3[ array_size ];

for ( int ix = 0; ix < array_size; ++ix ) ia2[ ix ] = ia1[ ix ];

return 0;

}

В качестве индекса массива может выступать любое выражение, дающее результат целого

int someVal, get_index();

типа. Например:

ia2[ get_index() ] = someVal;

Подчеркнем, что язык С++ не обеспечивает контроля индексов массива ни на этапе компиляции, ни на этапе выполнения. Программист сам должен следить за тем, чтобы индекс не вышел за границы массива. Ошибки при работе с индексом достаточно распространены. К сожалению, не так уж трудно встретить примеры программ, которые компилируются и даже работают, но тем не менее содержат фатальные ошибки, рано или поздно приводящие к краху.

Упражнение 3.22

(a)

int

ia[

buf_size ];

(d)

int ia[ 2 *

7

-

14 ]

(b)

int

ia[

get_size() ];

(e)

char st[ 11

]

=

"fundamental";

Какие из приведенных определений массивов содержат ошибки? Поясните.

(c) int ia[ 4 * 7 - 14 ];

Упражнение 3.23

Следующий фрагмент кода должен инициализировать каждый элемент массива

int main() {

const int array_size = 10; int ia[ array_size ];

for ( int ix = 1; ix <= array_size; ++ix ) ia[ ia ] = ix;

// ...

значением индекса. Найдите допущенные ошибки:

}