Выбрать главу

Конечно, нет никаких ограничений на количество применяемых модификаторов типа.

int *(&arry)[10]=ptrs; // arry - ссылка на массив из десяти указателей

Читая это объявление изнутри наружу, можно заметить, что arry — это ссылка. Глядя направо, можно заметить, что объект, на который ссылается arry, является массивом размером 10. Глядя влево, можно заметить, что типом элемента является указатель на тип int. Таким образом, arry — это ссылка на массив десяти указателей.

Зачастую объявление массива может быть проще понять, начав его чтение с имени массива и продолжив его изнутри наружу.

Упражнения раздела 3.5.1

Упражнение 3.27. Предположим, что функция txt_size() на получает никаких аргументов и возвращают значение типа int. Объясните, какие из следующих определений недопустимы и почему?

unsigned buf_size = 1024;

(a) int ia[buf_size];   (b) int ia[4 * 7 - 14];

(c) int ia[txt_size()]; (d) char st[11] = "fundamental";

Упражнение 3.28. Какие значения содержатся в следующих массивах?

string sa[10];

int ia[10];

int main() {

 string sa2[10];

 int ia2[10];

}

Упражнение 3.29. Перечислите некоторые из недостатков использования массива вместо вектора.

3.5.2. Доступ к элементам массива

Подобно библиотечным типам vector и string, для доступа к элементам массива можно использовать серийный оператор for или оператор индексирования ([]) (subscript). Как обычно, индексы начинаются с 0. Для массива из десяти элементов используются индексы от 0 до 9, а не от 1 до 10.

При использовании переменной для индексирования массива ее обычно определяют как имеющую тип size_t. Тип size_t — это машинозависимый беззнаковый тип, гарантированно достаточно большой для содержания размера любого объекта в памяти. Тип size_t определен в заголовке cstddef, который является версией С++ заголовка stddef.h библиотеки С.

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

// подсчет количества оценок в кластере по десять: 0--9,

// 10--19, ... 90--99, 100

unsigned scores[11] = {}; // 11 ячеек, все со значением 0

unsigned grade;

while (cin >> grade) {

 if (grade <= 100)

  ++scores[grade/10]; // приращение счетчика текущего кластера

}

Единственное очевидное различие между этой программой и приведенной в разделе 3.3.3 в объявлении массива scores. В данной программе это массив из 11 элементов типа unsigned. Не столь очевидно то различие, что оператор индексирования в данной программе тот, который определен как часть языка. Этот оператор применяется с операндами типа массива. Оператор индексирования, используемый в программе в разделе 3.3.3, был определен библиотечным шаблоном vector и применялся к операндам типа vector.

Как и в случае строк или векторов, для перебора всего массива лучше использовать серийный оператор for. Например, все содержимое массива scores можно отобразить следующим образом:

for (auto i : scores) // для каждого счетчика в scores

 cout << i << " ";    // отобразить его значение

cout << endl;

Поскольку размерность является частью типа каждого массива, системе известно количество элементов в массиве scores. Используя средства серийного оператора for, перебором можно управлять и не самостоятельно.

Проверка значений индекса