netlib.narod.ru< Назад | Оглавление | Далее >

5.9. Указатели против многомерных массивов

Начинающие программировать на Си иногда не понимают, в чем разница между двумерным массивом и массивом указателей вроде name из приведенного примера. Для двух следующих определений:

  int a[10][20];
  int *b[10];

записи a[3][4] и b[3][4] будут синтаксически правильным обращением к некоторому значению типа int. Однако только a является классическим двумерным массивом: для двухсот элементов типа int будет выделена память, а вычисление смещения элемента a[строка][столбец] от начала массива будет вестись по формуле 20 * строка + столбец, учитывающей его прямоугольную природу. Для b же определено только 10 указателей, причем без инициализации. Инициализация должна задаваться явно — либо статически, либо в программе. Предположим, что каждый элемент b указывает на массив из 20 элементов, в результате где-то будет выделено пространство, в котором разместятся 200 значений типа int, и еще 10 ячеек будет выделено для указателей. Важное преимущество массива указателей в том, что строки такого массива могут иметь разные длины. Таким образом, каждый элемент массива b не обязательно указывает на массив из 20 элементов; один может указывать на два элемента, другой — на пятьдесят, а некоторые и вовсе могут ни на что не указывать.

Наши рассуждения здесь касались целых значений, однако чаще массивы указателей используются для работы со строками символов, различающимися по длине, как это было в функции month_name. Сравните определение массива указателей и соответствующий ему рисунок:

    char *name[] = {
        "Неправильный месяц",
        "Январь", "Февраль", "Март"
    };

Рис. 11.

с объявлением и рисунком для двумерного массива:

    char aname[][20] = {
        "Неправильный месяц",
        "Январь", "Февраль", "Март"
    };

Рис. 12.


Упражнение 5-9


Перепишите программы day_of_year и month_day, используя вместо индексов указатели.



netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz