Обращение к элементам массива

Понятие указателя

Указатель — это переменная. В отличие от простых переменных, непосредственно хранящих значение заданного типа, указатель – это переменная, хранящая адрес памяти, где размещено значение заданного типа. То есть, указатель хранит не само значение, а адрес, обратившись по которому, можно получить это значение.

Переменная-указатель (далее будем говорить просто — указатель) объявляется также, как и любые другие переменные, но после имени типа ставится звездочка.

int* ptrInt;

Здесь объявляется переменная ptrInt. Ее тип — указатель на переменную типа int.

Синтаксис описания указателя

Следующие формы записи для компилятора эквивалентны:

1. int* ptr;

2. int *ptr;

Тем не менее, тип переменной ptr – «указатель на int», поэтому чаще используется первая форма записи.

В программах, как правило, используется раздельное объявление указателей и переменных, однако вы можете встретить и смешанное объявление:

int* p, b;

В ней p – указатель на int, b – переменная типа int.

Адрес переменной и значение переменной по адресу

Рассмотрим две переменные: целочисленную переменную x и указатель на целочисленную переменную.

int x = 10;

int* p;

Чтобы получить адрес переменной, нужно перед ее именем написать & (амперсанд).

p = &x;

Данная конструкция будет выполняться справа налево. Сначала с помощью операции &, примененной к переменной x, будет получен адрес x. Затем этот адрес будет присвоен указателю p.

Есть и обратная операция. Чтобы получить значение переменной по ее адресу, следует написать * (звездочку) перед именем указателя, т.е. выполнить операцию косвенной адресации (получение значения переменной по ее адресу):

int y = *p;

Такая операция в русском языке называется «разыменование» (анг. dereference).


В данном примере с помощью операции * мы получим то значение, которое находится в памяти по адресу p и сохранили его в переменную y:

// example1. cpp

#include <iostream>

using std::cout;

using std::endl;

Int main()

{

int x = 10, y = 20;

int* p;

p = &x;

y = *p;

cout<<"value x = "<< x<<endl<<"address x = "<<&x<<endl<<endl;

cout<<"value p = "<< p<<endl<<"address p = "<<&p<<endl<<endl;

cout<<"value y = "<< y<<endl<<"address y = "<<&y<<endl<<endl;

return 0;

}

В указанном примере значение x и y будут одинаковы. А также адрес x и значение p.

Результаты работы программы:

=*x, =&p?
1.4. Адресная арифметика

К указателям можно применять операции ++ и --. На основе этого сделана адресация в массиве. Рассмотрим пример:

// Объявление и инициализация массива

int arr[5] = {1, 2, 3, 4, 5};

//Объявление указателя на int и инициализация его адресом нулевого элемента массива.

int* p = &arr[0]; // лучше int* p = arr;

// Увеличение значения p не просто на 1, а на 1 * sizeof(int)

p++;

Комментарии:

1. Т.к. имя массива является указателем на его первый элемент, то вторая строка может быть записана иначе:

int* p = arr;

Таким образом, в p лежит адрес начала массива. А обращение *p даст 1.

2. Оператор sizeof(int) возвращает количество байт для типа int в данной системе. После увеличения p на 1, p указывает не на следующий байт, а на первый байт из следующей четверки байтов. Программисту не нужно думать в данном случае о размере типа.

С указателем можно складывать (вычитать) число, представленное целочисленной переменной или целочисленной константой. Вычесть можно не только число, но и указатель из указателя (полезно, например, при обработке строк). Сложение двух указателей, умножение или деление указателя на число или на другой указатель не имеет смысла.

Обращение к элементам массива

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

Конструкция arr[i] будет преобразована компилятором к *(arr + i). К начальному адресу массива будет прибавлено число с учетом размерности типа данных. А затем будет взято значение по вычисленному адресу.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: