Урок 83. Адресная арифметика и индексация массива

   ⁄ 

 Обновлено 25 Сен 2017

  ⁄   

C++ позволяет выполнять целочисленные операции сложения или вычитания с указателями. Если ptr указывает на целое число, тогда ptr + 1 — это адрес следующего целочисленного значения в памяти после ptr. ptr - 1 – это адрес предыдущего целочисленного значения (перед ptr).

Обратите внимание, ptr + 1 не возвращает следующий любой адрес памяти, который находится сразу после ptr, но возвращает адрес памяти следующего объекта, тип которого совпадает с типом значения, на которое указывает ptr. Если ptr указывает на целочисленное значение (размер которого 4 байта), ptr + 3 будет возвращать третье целочисленное значение после ptr. Если ptr указывает на char, то ptr + 3 будет возвращать третье значение типа char после ptr.

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

Рассмотрим следующую программу:

Результат на компьютере автора:

002CF9A4
002CF9A8
002CF9AC
002CF9B0

Как вы можете видеть, каждый из этих адресов отличается на 4 (7C + 4 = 80 в шестнадцатеричной системе счисления). Это связано с тем, что размер типа int на компьютере автора — 4 байта.

Та же программа, но с short вместо int:

Результат:

002BFA20
002BFA22
002BFA24
002BFA26

Поскольку short занимает 2 байта, то каждый следующий адрес больше предыдущего на 2.

Расположение элементов массива в памяти

Используя оператор адреса (&), мы можем легко определить, что элементы массива расположены в памяти последовательно. То есть, элементы 0, 1, 2, …  размещены рядом, друг за другом, по порядку.

Результат на компьютере автора:

Element 0 is at address: 002CF6F4
Element 1 is at address: 002CF6F8
Element 2 is at address: 002CF6FC
Element 3 is at address: 002CF700

Обратите внимание, каждый из этих адресов по отдельности занимает 4 байта, как и размер типа int на компьютере автора.

Адресная арифметика, массивы и их индексация

В разделе выше мы узнали, что элементы массива расположены в памяти последовательно.

В уроке 82 мы узнали, что фиксированный массив может распадаться на указатель, который указывает на первый элемент (элемент 0) в массиве.

Также в разделе выше мы узнали, что добавление 1 к указателю возвращает адрес памяти следующего объекта этого же типа данных.

Следовательно, можно предположить, что добавление 1 к массиву приведет к возврату второго элемента (элемент 1) массива. Проверим на практике:

При разыменовании результата выражения адресной арифметики скобки необходимы для обеспечения правильности приоритета операций, поскольку оператор * имеет более высокий приоритет, чем оператор +.

Результат на компьютере автора:

001AFE74
001AFE74
8
8

Оказывается, когда компилятор видит оператор индекса ([]), он на самом деле конвертирует его в указатель с операцией сложения и разыменования! То есть, array[n] – это тоже самое, что и *(array + n), где n – целочисленное значение. Оператор индекса [] используется в целях удобства, чтобы не нужно было всегда помнить о скобках.

Использование указателя для итерации по массиву

Мы можем использовать указатели и адресную арифметику для выполнения итераций по массиву. Хотя обычно это не делается (использование оператора индекса, как правило, читабельнее и менее подвержено ошибкам), следующий пример показывает, что это возможно:

Как это работает? Программа использует указатель для прогона каждого элемента в массиве поочередно. Помните, что массив распадается на указатель на первый элемент массива? Поэтому, присвоив name для ptr, ptr стал указывать на первый элемент в массиве. Каждый элемент разыменовывается с помощью выражения switch, и, если текущий элемент массива является гласной буквой, numVowels увеличивается. Для перемещения указателя на следующий символ (элемент) массива в цикле for используется оператор ++. Работа цикла завершится, когда все символы будут проверены.

Результат выполнения программы выше:

Jonathan has 3 vowels.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (2 оценок, среднее: 5,00 из 5)
Загрузка...
Поделиться в:
Подписаться на обновления:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *