[ Советы ]
_________________
116 стр. Часть 2. Становимся функциональными программистами
Глава 9. ВТОРОЕ ЗНАКОМСТВО С УКАЗАТЕЛЯМИ...117
ОГЛАВЛЕНИЕ
В этой главе...
►Операции с указателями 117
►Объявление и использование массивов указателей 124
Язык С++ позволяет работать с указателями так, как если бы они были переменными простых типов. ( Концепция указателей изложена в главе 8, "Первое знакомство с указателями в С++". ) Однако операции над указателями требуют знания некоторых тонкостей; именно они и рассматриваются в этой главе.
►Операции с указателями...117
Некоторые из операций, описанных в главе 3, "Выполнение математических операций", могут быть применены и к указателям. В этом разделе рассматривается использование арифметических операций при работе с указателями и массивами ( с массивами вы познакомились в главе 7, "Хранение последовательностей в массивах"). В табл. 9.1 приведены базовые операции над указателями.
Таблица 9.1. Три операции над указателями
_________________
Операция — Результат — Действие
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
pointer+offset — Указатель — Вычисляет адрес элемента, расположенного через offset элементов после pointer
pointer-offset — Указатель — Операция, противоположная сложению
pointer2-pointer1 — Смещение — Вычисляет количество элементов между pointer1 и pointer2
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
В этой таблице offset имеет тип int ( здесь не приведены операции, близкие к сложению и вычитанию, такие как ++ и +=, которые также могут применяться к указателям ).
Модель памяти, построенная на примере домов ( так эффективно использованная в предыдущей главе ), поможет понять, как работают приведённые в таблице операции с указателями. Представьте себе квартал, в котором все дома пронумерованы по порядку. Дом, следующий за домом 123 Main Street, будет иметь адрес 124 Main Street ( или 122 Main Street, если вы идёте в противоположную сторону, поскольку вы левша или живёте в Англии ).
Очевидно, что в таком случае через четыре дома от моего будет находиться дом с адресом 127 Main Street. Адрес этого дома можно записать как
123 Main Street + 4 = 127 Main Street
_________________
117 стр. Глава 9. Второе знакомство с указателями
И наоборот, если поинтересоваться, сколько домов находится между домом 123 и 127, ответом будет четыре:
127 Main Street - 123 Main Street = 4
Понятно, что любой дом находится относительно самого себя на расстоянии нуль домов:
123 Main Street - 123 Main Street = 0
Продолжая рассуждения, становится понятно, что складывать дома 123 и 127 не имеет никакого смысла. Соответственно, суммирование двух указателей является в С++ некорректной операцией. Вы также не можете умножать или делить адреса, возводить их в квадрат или извлекать квадратный корень — словом, надеюсь, вы поняли, что я хотел сказать.
Повторное знакомство с массивами в свете указателей...118
Обратимся к странному и мистическому миру массивов. Ещё раз воспользуемся в качестве примера домами моих соседей. Массив тоже очень похож на городской квартал. Каждый элемент массива выступает в качестве дома в этом квартале. Дома — элементы массива — отсчитываются по порядку от начала квартала. Дом на углу улицы отстоит на 0 домов от угла, следующий дом отстоит на 1 дом от угла и т.д. Пользуясь терминологией массивов, можно сказать, что cityBlock[ 0 ] представляет собой дом по адресу 123 Main Street, cityBlock[ 1 ] — дом по адресу 124 Main Street и т.д.
Теперь представим себе массив из 32-х однобайтовых значений, имеющий имя charArray . Если первый элемент массива находится по адресу 0x110 , тогда массив будет продолжаться вплоть до адреса 0x12f. Таким образом, элемент массива charArray[ 0 ] находится по адресу 0x110 , charArray[ 1 ] — по адресу 0x111 , charArray[ 2 ] — по адресу 0x112 и т.д.
Можно создать указатель ptr на нулевой элемент массива. После выполнения строки ptr = & charArray[ 0 ] ; указатель ptr будет содержать адрес 0x110. Можно прибавить к этому адресу целочисленное смещение и перейти к необходимому элементу массива. Операции над массивами с использованием указателей приведены в табл. 9.2. Эта таблица демонстрирует, каким образом добавление смещения n вызывает переход к следующему элементу массива charArray .
Таблица 9.2. Добавление смещения
_________________
Смещение — Результат — Соответствует
Читать дальше