Язык программирования C

Массивы, указатели и индексация


Каждый раз, когда идентификатор, имеющий тип массива, появляется в выражении, он преобразуется в указатель на первый член этого массива. Из-за этого преобразования массивы не являются L-значениями. По определению операция индексация [] интерпретируется таким образом, что e1[e2] считается идентичным выражению *((e1)+(e2)). Согласно правилам преобразований, применяемым при операции +, если e1 - массив, а e2 - целое, то e1[e2] ссылается на e2-й член массива e1. Поэтому несмотря на несимметричный вид операция индексации является коммутативной.

В случае многомерных массивов применяется последовательное правило. Если e является n-мерным массивом размера i*j*...*k, то при появлении в выражении e преобразуется в указатель на (n-1)-мерный массив размера j*...*k. Если операция * либо явно, либо неявно, как результат индексации, применяется к этому указателю, то результатом операции будет указанный (n-1)-мерный массив, который сам немедленно преобразуется в указатель.

Рассмотрим, например, описание

int x[3][5];

Здесь x массив целых размера 3*5. При появлении в выражении x преобразуется в указатель на первый из трех массивов из 5 целых. В выражении x[i], которое эквивалентно *(x+i), сначала x преобразуется в указатель так, как описано выше; затем i преобразуется к типу x, что вызывает умножение i на длину объекта, на который указывает указатель, а именно на 5 целых объектов. Результаты складываются, и применение косвенной адресации дает массив (из 5 целых), который в свою очередь преобразуется в указатель на первое из этих целых. Если в выражение входит и другой индекс, то таже самая аргументация применяется снова; результатом на этот раз будет целое.

Из всего этого следует, что массивы в языке "C" хранятся построчно (последний индекс изменяется быстрее всего) и что первый индекс в описании помогает определить общее количество памяти, требуемое для хранения массива, но не играет никакой другой роли в вычислениях, связанных с индексацией.



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