Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2009 лекции ПЯВУ часть1.doc
Скачиваний:
22
Добавлен:
27.03.2015
Размер:
823.3 Кб
Скачать

5.2. Выражения и арифметические действия с указателями

С указателями [1] может выполняться ограниченное количество арифметических операций. Указатель можно увеличивать (++), уменьшать (--), складывать с указателем целые числа (+или+=), вычитать из него целые числа (-или-=) или вычитать один указатель из другого.

Допустим, что объявлен массив int v[10]и его первый элемент находится в памяти в ячейке3000. Допустим, что указателюvPtrбыло присвоено начальное значение путем указания наv[0], т.е. начальное значениеvPtrравно3000(см. рис. 5.2).

Указателю vPtrможно было дать начальное значение указанием на массивvс помощью одного из следующих операторов:

vPtr = v;

vPtr = &v[0];

В общепринятой арифметике сложение 3000 + 2дает значение3002. Это нормально, но не в случае арифметических действий с указателями. Когда целое складывается или вычитается из указателя, указатель не просто увеличивается или уменьшается на это целое, но это целое предварительно умножается на размер объекта, на который ссылается указатель. Количество байтов зависит от типа данных. Например, оператор

vPtr +=2;

выработал бы значение 3008 (3000 + 2*4)в предположении, что целое хранится в 4 байтах памяти. В массивеvуказательvPtrтеперь указал бы наv[2]. Если целое хранится в 2 байтах памяти, то тот же самый оператор дал бы результат в памяти ячейку3004 (3000+2*2). И т.д.

Ячейка

3000 3004 3008 3012 3016

Переменная указатель vPtr

V[0] V[1] V[2] V[3] V[4]

Рис. 5.2. Указатель на массив целых чисел

Если указатель vPtrбыл увеличен до значения3016, указывающего наv[4], оператор

vPtr -= 4;

вернул бы vPtrобратно к значению3000– к началу массива. Если указатель увеличивается или уменьшается на 1, можно использовать операции инкремента (++) или декремента (--).

Переменные указатели можно вычитать друг из друга. Например, если vPtrсодержит ячейку3000,v2Ptrсодержит адрес3008, оператор

x = v2Ptr – vPtr;

присвоит хзначение разности номеров элементов массива, на которые указываютvPtrиv2Ptr, в данном случае2.

Арифметика указателей теряет смысл, если она выполняется не над массивами. Нельзя предполагать, что две переменные одинакового типа хранятся в памяти вплотную друг к другу, если они не соседствуют в массиве.

5.3. Взаимосвязи между указателями и массивами

Массивы и указатели в С++ тесно связаны и могут быть использованы почти эквивалентно. Имя массива можно понимать как указатель, постоянно ссылающийся на первый элемент массива (константный указатель). Указатели можно использовать для выполнения любой операции, включая индексирование массива.

Предположим, объявлены массив целых чисел b[5]и целая переменная-указательbPtr. Поскольку имя массива (без индекса) является указателем на первый элемент массива, то можно задать указателюbPtrадрес первого элемента массиваbс помощью оператора

bPtr = b;

это эквивалентно присваиванию адреса первого элемента массива следующим образом:

bPtr = &b[0];

Сослаться на элемент массива b[3]можно с помощью выражения указателя

*(bPtr + 3)

В приведенном выражении цифра 3являетсясмещениемуказателя. Когда указатель указывает на начало массива, смещение показывает, на какой элемент массива должна быть ссылка, так что значение смещения эквивалентно индексу массива. Предыдущую запись называют записьюуказатель-смещение. Скобки необходимы, потому что приоритет*выше, чем приоритет.+. Без скобок это выражение прибавило бы число3к значению выражения*bPtr(т.е.3было бы прибавлено кb[0]в предположении, чтоbPtrуказывает на начало массива).

Сам массив можно рассматривать как указатель и использовать в арифметике указателей.

Например, выражение

*(b + 3)

тоже ссылается на элемент массива b[3]. Вообще все выражения с индексами массива могли бы быть записаны с помощью указателей и смещений. В этом случае запись указатель-смещение применялась бы к имени массива как к указателю.

Указатели можно индексировать точно так же, как и массивы. Например, выражение

bPtr[1]

ссылается на элемент массива b[1], это выражение рассматривается как записьуказатель-индекс.

Имя массива является константнымуказателем, оно всегда указывает на начало массива. Поэтому выражение

b += 3;

не разрешено, потому что оно пытается модифицировать значение имени массива с помощью арифметической операции над указателем.