a16b2e27

Ссылки и массивы 1.1.


int a [] = { 0, 1, 2, 3, 4 }; Переменная a определена как массив из пяти целых с элементами a[i]=i для i от 1 до 4.
for ( i=0; i<=4; i++ ) Переменная i принимает значение от 1 до 4.
PR(d, a[i]); a[i] последовательно пробегает все элементы массива a.




int *p; Описание вида type *x сообщает транслятору, что когда *x появляется в выражениях, то это значение типа type. Переменная x - ссылка на переменные типа type и принимает в качестве значения адреса переменных типа type. type - базовый тип для x. В этой задаче переменная p описана как ссылка на целое, т.е. базовый тип для p - int.
for ( p=&a[0]; &a[0] дает адрес a[0].
p<=&a[4]; Элементы массива хранятся в памяти в порядке возрастания индексов, т.е. a[0] предшествует a[1], которое предшествует a[2], и т.д. Так что p, инициируемое значением &a[0], меньше, чем &a[4].
PR(d, *p); Выражение *p дает целое, хранящееся по адресу, содержащемуся в p. Поскольку p содержит &a[0], то *p есть a[0].
p++ Если к ссылке применить операцию увеличения, то она будет указывать на следующий элемент базового типа. Фактически же значение ссылки увеличивается на sizeof(базовый тип). В языке не предполагается проверка того, что получившийся в результате адрес действительно есть адрес доступного элемента базового типа. В этой задаче p будет указывать на следующий элемент массива a.
p<=&a[4]; Значение p проверяется на конец массива a. Цикл заканчивается, когда p будет указывать на последний элемент массива. В теле цикла p последовательно указывает на элементы массива в порядке возрастания индексов.




for ( p=&a[0], i=1; I<=5; i++ ) Переменная p указывает на начало массива a. Переменная i пробегает значения от 1 до 5.
PR(d, p[i]); Ссылка p[i] последовательно указывает на элементы массива a. Ссылка p[5] указывает за массив a.

О массивах и индексах. Хотя до сих пор обозначение [] находило свое обычное применение - индексация массива, на самом деле [] обозначает общую операцию индексирования. x[i] определяется как *(x+i), где x обычно является адресом и i - целое. В соответствии с правилами адресной арифметики i должно быть кратно sizeof(базовый тип x). (К этому моменту должно быть ясно, почему массивы индексируются начиная с 0. Имя массива по сути есть ссылка на первый элемент массива. Индекс - это смещение относительно начала массива. Смещение первого элемента относительно начала массива равно 0.) В предыдущем фрагменте i используется для индексации ссылки p. p[i] = (p+i) = *(a+i) = a[i]. Переменная i пробегает значения от 1 до 5. Когда i=5, p+i указывает за массив a, т.е. значение, находящееся по адресу p+i неизвестно. Это настолько распространенная ошибка, что стоит подчеркнуть опять: индекс массива из n элементов принимает значения от 0 до n-1.




for ( p=a, i=0; Ссылке p присваивается адрес первого элемента a.
p+i<=a+4; p=a, i=0, так что p+i=a+0, что меньше, чем a+4.
PR(d, *(p+i)); *(p+i) = *(a+0) = a[0].
p++, i++ ) p указывает на второй элемент a, i равно 1.
p+i<=a+4; p=a+1, i=1, значит, p+i=a+2.
PR(d, *(p+i)); *(p+i)=a[2].
p++, i++ ) p=a+2, i=2.
p+i<=a+4; p+i=a+4.
PR(d, *(p+i)); *(p+i)=a[4].
p++, i++ ) p=a+3, i=3.
p+i<=a+4; p+i=a+6, и цикл заканчивается.




for ( p=a+4; Ссылка p указывает на пятый элемент массива a.
p>=a; Цикл заканчивается, когда p указывает за a.
PR(d, *p); Печатается целое, на которое указывает p.
p-- При уменьшении p настраивается на предыдущий элемент массива.




for ( p=a+4, i=0; i<=4; i++ ) Ссылка p указывает на последний элемент массива a. i пробегает от 0 до 4.
PR(d, p[-i]); Печатается i-й от конца элемент массива.




for ( p=a+4; p>=a; p-- ) Ссылка p последовательно указывает на все элементы массива a от последнего до первого.
PR(d, a[p-a]); Значение p-a равно смещению элемента массива, на который указывает p от начала. Другими словами, p-a есть индекс элемента, на который указывает p.



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