Бьерн Страуструп - Язык программирования С++. Главы 2-4 - Массивы

ОГЛАВЛЕНИЕ


2.3.6  Массивы

Для типа T T[size] является типом "массива из size элементов типа T". Элементы индексируются от 0 до size-1. Например:
     float v[3];   // массив из трех чисел с плавающей точкой:
                   //     v[0], v[1], v[2]
     int a[2][5];  // два массива, из пяти целых каждый
     char* vpc;    // массив из 32 символьных указателей
Можно следующим образом записать цикл, в котором печатаются целые значения прописных букв:
     extern "C" int strlen(const char*);  // из <string.h>

     char alpha[] = "abcdefghijklmnopqrstuvwxyz";

     main()
     {
       int sz = strlen(alpha);

       for (int i=0; i<sz; i++) {
           char ch = alpha[i];
           cout << '\''<< ch << '\''
                << " = " <<int(ch)
                << " = 0" << oct(ch)
                << " = 0x" << hex(ch) << '\n';
        }
     }
Здесь функции oct() и hex() выдают свой параметр целого типа в восьмеричном и шестнадцатеричном виде соответственно. Обе функции описаны в <iostream.h>. Для подсчета числа символов в alpha
используется функция strlen() из <string.h>, но вместо нее можно было использовать размер массива alpha ($$2.4.4). Для множества символов ASCII результат будет таким:

     'a' = 97 = 0141 = 0x61
     'b' = 98 = 0142 = 0x62
     'c' = 99 = 0143 = 0x63
     ...

Отметим, что не нужно указывать размер массива alpha: транслятор установит его, подсчитав число символов в строке, заданной в качестве инициализатора. Задание массива символов в виде строки инициализатора
- это удобный, но к сожалению, единственный способ подобного применения строк. Присваивание строки массиву недопустимо, поскольку в языке присваивание массивам не определено, например:
      char v[9];
      v = "a string";          // ошибка

Классы позволяют реализовать представление строк с большим набором операций (см. $$7.10).

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

      int  v1[] = { 1, 2, 3, 4 };
      int  v2[] = { 'a', 'b', 'c', 'd' };

      char v3[] = { 1, 2, 3, 4 };
      char v4[] = { 'a', 'b', 'c', 'd' };
Здесь v3 и v4 - массивы из четырех (а не пяти) символов; v4 не оканчивается нулевым символом, как того требуют соглашение о строках и большинство библиотечных функций.  Используя такой массив char мы сами готовим почву для будущих ошибок.

Многомерные массивы представлены как массивы массивов. Однако нельзя при задании граничных значений индексов использовать, как это делается в некоторых языках, запятую. Запятая - это особая операция для перечисления выражений (см. $$3.2.2). Можно попробовать задать такое описание:

      int bad[5,2];    // ошибка
или такое
      int v[5][2];
      int bad = v[4,1];      // ошибка
      int good = v[4][1];    // правильно
Ниже описывается массив из двух элементов, каждый из которых является, в свою очередь, массивом из 5 элементов типа char:
      char v[2][5];
В следующем примере первый массив инициализируется пятью первыми буквами алфавита, а второй - пятью младшими цифрами.
      char v[2][5] = {
           { 'a', 'b', 'c', 'd', 'e' },
           { '0', '1', '2', '3', '4' }
      };

      main() {
          for (int i = 0; i<2; i++) {
            for (int j = 0; j<5; j++)
                cout << "v[" << i << "][" << j
                     << "]=" << v[i][j] << "  ";
                cout << '\n';

          }
      }
  В результате получим:

     v[0][0]=a v[0][1]=b v[0][2]=c v[0][3]=d v[0][4]=e
     v[1][0]=0 v[1][1]=1 v[1][2]=2 v[1][3]=3 v[1][4]=4