Взаимосвязи между указателями и массивами
Массивы и указатели в C++ тесно связаны и могут быть использованы почти эквивалентно. Имя массива можно понимать как константный указатель. Указатели можно использовать для выполнения любой операции, включая индексирование массива.
Предположим, что объявлены массив целых чисел b[5] и целая переменная-указатель bPtr. Поскольку имя массива (без индекса) является указателем на первый элемент массива, мы можем задать указателю bPtr адрес первого элемента массива b с помощью оператора:
bPtr = b;
чтo эквивалентно присваиванию адреса первого элемента массива следующим образом:
bPtr= &b[0];
Сослаться на элемент массива b[3] можно с помощью выражения указателя
*( bPtr + 3 )
В приведенном выражении 3 является смещением указателя. Когда указатель указывает на начало массива, смещение показывает, на какой элемент массива должна быть ссылка, так что значение смещения эквивалентно индексу массива. Предыдущую запись называют записью yкaзатeль-cмeщeнue (poiпter/offset notation). Скобки необходимы, потому что приоритет * выше, чем приоритет +. Без скобок верхнее выражение прибавило бы 3 к значению выражения *bPtr (т.е. 3 было бы прибавлено кb[0] в предположении, что bPtr указывает на начало массива). Поскольку элемент массива может быть задан указателем-выражением, адрес
&b[3] ,
может быть записан также выражением - указателем
bPtr + 3
Cам массив можно рассматривать как указатель и использовать в арифметике указателей. Например, выражение
*( b +3 )
тоже ссылается на элемент массива b[3]. Вообще, все выражения с индексами массива могли бы быть записаны с помощью указателей и смещений. В этом случае запись указатель-смещение применялась бы к имени массива как к указателю. Заметим, что предыдущий оператор никоим образом не модифицирует имя массива;bпродолжает указывать на первый элемент массива.
Указатели молено индексировать точно так же, как и массивы. Например, выражение
bPtr[1]
ссылается на элемент массива b[1]; это выражение рассматривается как запись указатель-индекс (pointer/subscript notation). Запомним, что имя массива, по существу, является постоянным указателем; оно всегда указывает на начало массива. Таким образом, выражение
b += 3
Не разрешено, потому что оно «пытается» модифицировать значение имени массива с помощью арифметической операции над указателем.
Пример: Использованы четыре обсужденных нами метода ссылок на элементы массива (индексирование массива, указатель-смещение с именем массива как указателем, индексирование указателя и указатель-смещение с указателем) для печати четырех элементов массива целых чисел b.
#include <iostream.h>
#include <conio.h>
int main() {
int b[]= {10, 20, 30, 40 };
int i, offset;
int *bPtr = b;
cout<< "massiv b c indexsami :\n" ;
for ( i = 0; i < 4; i++ )
cout << "b["<< i <<"]="<<b[i]<<'\n';
cout <<"\nukazatel'/smecshenie\n";
for ( offset = 0; offset < 4; offset++ )
cout<< "*(b + "<< offset<< ")="<< *( b + offset )<<'\n';
cout << "\nnotachii indexa ukazatela\n";
for ( i = 0; i < 4; i++ )
cout << "bPtr["<< i << "]= "<<bPtr[ i ]<<'\n';
cout<< "\nNotachii ukazatel'\smecshenie\n";
for ( offset = 0; offset < 4; offset++ )
cout <<"*(bPtr + "<< offset<<") = " <<*( bPtr + offset )<<'\n';
getch();
return 0;
}
Результат работы программы:
massiv b c indexsami :
b[0]=10
b[1]=20
b[2]=30
b[3]=40
ukazatel'/smecshenie
*(b + 0)=10
*(b + 1)=20
*(b + 2)=30
*(b + 3)=40
notachii indexa ukazatela
bPtr[0]= 10
bPtr[1]= 20
bPtr[2]= 30
bPtr[3]= 40
Notachii ukazatel'smecshenie
*(bPtr + 0) = 10
*(bPtr + 1) = 20
*(bPtr + 2) = 30
*(bPtr + 3) = 40