Информатика и технология программирования

         

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


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



-двумерный массив всегда реализован как одномерный массив с количеством элементов, соответствующих первому индексу, причем каждый элемент представляект собой массив элементов базового типа с количеством, соответствующим второму индексу. Например,




char A[20][80];



определяет массив из 20 массивов по 80 символов в каждом и никак иначе. Массив, таким образом, располагается в памяти по строкам;



-идентификатор массива без скобок интерпретируется как адрес нулевого элемента нулевой строки, или указатель на базовый тип данных. В нашем примере идентификатору A будет соответствовать выражение &#38A[0][0] с типом char*;



-по аналогии имя двумерного массива с единственным индексом интерпретируется как начальный адрес соответствующего внутреннего одномерного массива. A[i] понимается как &#38A[i][0], то есть начальный адрес i-го массива символов.

Сказанное справедливо и для многомерных массивов: многомерный массив представляет собой массив элементов первого индекса, каждый из который представляет собой массив элементов второго индекса и т.д..


extern void gets(char*);
char A[20][80];
int i;
for (i=0; i&#60 20; i++) // А[i] - указатель на i-ю строку


gets(A[i]); // в двумерном массиве символов

Как известно, обычный указатель работает с линейной последовательностью элементов. В этом случае при присваивании начального адреса двумерного массива обычному указателю его двумерная структура " теряется" . В следующем примере указатель используется для работы с двумерным массивом с учетом его реального размещения в памяти:


char *q,A[20][80];
q = A;
*(q + i*80 + j) // или


q[i*80 + j]

Для работы с многомерными массивами вводятся особые указатели -указатели на массивы. Они представляют собой обычные указатели, адресуемым элементом которых является не базовый тип, а массив элементов этого типа:


char (*p)[][80];
char (*q)[5][80];

Заметим, что круглые скобки имеют здесь принципиальное значение. В контексте определения p является переменной, при косвенном обращении к которой получается двумерный массив символов, то есть p является указателем на двумерный массив. При отсутствии скобок имел бы место двумерный массив указателей на строки. Кроме того, если не используются операции вида p++ или p+=n , связанные с размерностью указуемого массива, то наличия первого индекса не требуется.




p = q = A; // назначить p и q на двумерный массив


(*p)[i][j]... // j-ый символ в i-ой строке


// в массиве по указателю p


p+=2; // переместить p на 2 массива


// по 5 строк по 80 символов



Содержание раздела