Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
Адресная арифметика

Адресная арифметика

31 Мар 2013

Адресная арифметика (address arithmetic) — это способ вычисления адреса какого-либо объекта при помощи арифметических операций над указателями, а также использование указателей в операциях сравнения. Адресную арифметику также называют арифметикой над указателями (pointer arithmetic).

Согласно стандартам языков С и С++, при арифметике с указателями результирующий адрес должен оставаться строго на границе единичного объекта массива (или следовать сразу за ним). Сложение или вычитание указателя сдвигает его на величину, кратную размеру того типа данных, на который он указывает. Например, есть указатель на массив целых чисел (по 4 байта на каждый элемент). Инкремент этого указателя приведет к увеличению его значения на 4 (размер элемента). Этой особенностью часто пользуются, чтобы получить N-ый элемент в последовательном контейнере.

int array[10] {};
int *ptr  = array;   // points to the first element
int *next = ptr + 1; // points to the second element
....
int *next = ptr + 9; // points to the last element

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

struct SomeType;          // Incomplete type
....
SomeType* ptr  = ....;
SomeType* next = ptr + 1; // ERROR: 'SomeType *': unknown size

Однако существуют нестандартные расширения компилятора, позволяющие выполнять байтовую арифметику на нетипизированных указателях (void *).

Указатели и целочисленные переменные не являются взаимозаменяемыми объектами. Константа нуль — единственное исключение из этого правила: её можно присвоить указателю, который можно сравнить с нулевой константой. Чтобы показать, что нуль — это специальное значение для указателя, вместо цифры 0, как правило, записывают константу 'NULL'. Начиная с С23 / C++11, для этих целей лучше использовать nullptr.

Адресная арифметика даёт программисту возможность работать с разными типами одинаковым способом: за счёт сложения и вычитания необходимого числа элементов вместо действительного сдвига байтов. В частности, описание языка С явно задаёт равнозначность синтаксической структуры A[i], которая является i-ым элементом массива A, и *(A + i), которая представляет собой содержимое элемента, на который указывает выражение (A + i). Также подразумевается, что i[A] равнозначно A[i]. Другими словами, все четыре указателя из примера ниже указывают на один и тот же элемент, просто разными способами:

int *a = array + 2;
int *b = 2 + array;
int *c = array[2];
int *d = 2[array];

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

Из-за сложностей использования указателей многие современные языки программирования высокого уровня (например, Java или C#) не разрешают прямой доступ к памяти с использованием адресов.

Список источников

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам