68. Арифметика указателей
К указателям можно применять некоторые арифметические операции. К таким операциям относятся: +, -, ++, --. Результаты выполнения этих операций по отношению к указателям существенно отличаются от результатов соответствующих арифметических операций, выполняющихся с обычными числовыми данными.
Рассмотрим следующий пример:
int A = 20, B = 30;
int *p1 = &A;
Пусть переменные A и B расположены в памяти, например, так, как это показано на следующем рисунке:
A = 20 B = 30 p1 = 100
… 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 …
Указатель p1 содержит адрес переменной A, который равен 100 и *p1 будет равно значению переменной A, то есть 20. Выполним следующую операцию:
p1 = p1 + 1;
или, что то же самое:
p1++;
Значение указателя изменится и станет равным 104, а не 101, как, наверное, ожидалось. То есть теперь указатель ссылается уже на переменную B и значение *p1 будет равно 30.
Таким образом, добавление или вычитание 1 из указателя приводит к изменению его значения на размер базового типа указателя. В общем случае, например, при выполнении следующей операции:
p1 = p1 + N; // N – некоторое целое значение
значение указателя увеличится на sizeof(<базовый тип указателя>) * N и в нашем случае это приращение будет равно sizeof(int) * N = 4 * N. Так, если N = 4, а p1 = 100 , то значение указателя p1 увеличится на 16 и станет равно 116, и указатель будет ссылаться на данные, расположенные по адресу 116.
Внимание. Добавлять к указателям или вычитать из указателей можно только целые значения.
Поскольку упомянутые арифметические операции выполняются по-разному при их применении к указателям и обычным арифметическим типам данных, а также учитывая высший приоритет операции *, при использовании указателей в составе выражений следует внимательно обращаться со скобками. Например, выражения (см. предыдущий рисунок)
*(p1 + 1) и *p1 + 1
имеют совершенно разный смысл. Первое выражение даст значение 30, а второе выражение будет равно 21 (в первом выражении сначала изменяется адрес, а затем осуществляется обращение в память по этому измененному адресу; во втором выражении мы обращаемся по старому адресу и к значению, хранящемуся по этому адресу добавляем 1).
- 2. Структура и основные элементы программы
- 3.Общее понятие типов данных
- 4. Переменные и константы
- 5.Основные типы данных
- 6. Спецификаторы типов данных
- 7. Определение переменных и констант в программе
- 8. Инициализация переменных различных типов
- 9.Целочисленные типы данных
- 10. Вещественные типы данных
- 11. Особенности представления вещественных типов данных
- 12.Логический тип данных
- 13. Символьный тип данных
- 14. Управляющие последовательности
- 15. Операции и выражения
- 16. Операция присваивания, составные операции присваивания
- 17. Понятие l-значения
- 18. Преобразование типов данных
- 19. Арифметические операции
- 20. Операции инкремента и декремента, их разновидности
- 21. Операции отношения
- 22. Логические операции
- 23. Побитовые операции сдвига
- 24. Побитовые логические операции
- 25. Примеры применения побитовых операций
- 26. Условная операция и ее использование
- 27. Определение объема памяти, необходимого для размещения объектов
- 28. Понятие приоритета операций и его влияние на результаты вычислений
- 31.Флаги форматирования потоков ввода-вывода
- 32. Форматирование ввода-вывода с помощью манипуляторов
- 33.Форматирование ввода-вывода с помощью функций потоков ввода-вывода
- 34. Управление шириной поля вывода и выравниванием данных при выводе
- 35. Управление форматом вывода вещественных значений
- 36. Основные понятия структурного программирования
- 37. Базовый набор управляющих структур
- 39.Условная инструкция (if)
- 40. Инструкция множественного выбора (switch)
- 42. Цикл с постусловием (do while)
- 43. Итерационный цикл (for)
- 46. Инструкция перехода goto
- 47. Понятие рекуррентных вычислений, примеры
- 48. Понятие инварианта цикла
- 49. Понятие и определение массива
- 52. Ввод элементов массивов с клавиатуры
- 53. Декларативная и программная инициализация массивов
- 54. Копирование массивов
- 55. Нахождение минимальных и максимальных значений в массивах
- 56. Сдвиг элементов массивов
- 57. Перестановка элементов в массивах
- 58. Поиск данных в массивах
- 59. Сортировка данных в массивах
- 60. Вычисление сумм и произведений элементов массивов
- 61. Представление текстовых строк в виде массива символов
- 62. Ввод-вывод символьных строк
- 63. Определение фактической длины строки
- 64. Копирование символьных строк
- 65. Основные функции обработки строк библиотеки cstring
- 66. Массивы текстовых строк (двумерные массивы символов)
- 67. Указатели Понятие указателя
- Работа с указателями
- 68. Арифметика указателей
- 69. Индексирование указателей
- 70. Ссылки
- 71. Определение функции
- 72. Инструкция return
- 73. Завершение работы функции
- 74. Механизмы передачи данных через параметры функций
- 75. Передача данных по значению
- 76. Передача данных через указатели
- 77. Передача данных по ссылке
- 78. Параметры по умолчанию
- 79. Функции с переменным числом параметров
- 80. Inline функции
- 81. Перегрузка функций
- 82. Рекурсия
- 83. Прототипы функций