Адресная арифметика
Адресная арифметика (address arithmetic) - это способ вычисления адреса какого-либо объекта при помощи арифметических операций над указателями, а также использование указателей в операциях сравнения. Адресную арифметику также называют арифметикой над указателями (pointer arithmetic).
Согласно стандартам языка Си и Си++, при арифметике с указателями, результирующий адрес должен оставаться строго на границе единичного объекта массива (или следовать сразу за ним). Сложение или вычитание указателя сдвигает его на величину, кратную размеру того типа данных, на который он указывает. Пример. Пусть есть указатель на массив 4-байтных целых. Инкремент этого указателя приведет к увеличению его значения на 4 (размер элемента). Такой эффект часто используется для увеличения указателя для того, чтобы он указывал на следующий элемент в смежном массиве целых чисел.
Арифметика с указателями не может быть применена к указателям на неизвестные типы, поскольку неизвестные типы не имеют размера, и соответственно адрес, на который ссылается указатель, не может быть прибавлен к нему. Однако, иногда существуют нестандартные расширения компилятора, позволяющие выполнять байтовую арифметику на нетипизированных указателях (void *).
Указатели и целочисленные переменные не являются взаимозаменяемыми объектами. Константа нуль — единственное исключение из этого правила: ее можно присвоить указателю, и указатель можно сравнить с нулевой константой. Чтобы показать, что нуль — это специальное значение для указателя, вместо цифры нуль, как правило, записывают константу NULL.
Арифметика с указателями дает программисту возможность работать с разными типами одинаковым способом: за счет сложения и вычитания необходимого числа элементов вместо действительного сдвига байтов. В частности, описание языка Си явно задает равнозначность синтаксической структуры A[i], которая является i-ым элементом массива A, и *(A+i), которая представляет собой содержание элемента, на который указывает выражение A+i. Также подразумевается, что i[A] равнозначно A[i].
В то же время мощная арифметика с указателями может стать причиной ошибок. Адресная арифметика является сдерживающим этапом при освоении 64-битных систем, поскольку старый программный код на языках Си/Си++ может содержать большое количество ошибок связанных с использованием указателей. Более подробно с данной проблемой можно познакомиться в статье "20 ловушек переноса Си++ - кода на 64-битную платформу".
Из-за сложностей использования указателей многие современные языки программирования высокого уровня (например, Java или C#) не разрешают прямой доступ к памяти с использованием адресов.
Библиографический список
- Б.В. Керниган, Д.М. Ричи. Язык Си. (Глава 5.4. Адресная арифметика).
- Wikipedia. Pointer (computing). https://en.wikipedia.org/wiki/Pointer_(computer_programming)
- Андрей Карпов, Евгений Рыжков. 20 ловушек переноса Си++ - кода на 64-битную платформу. http://www.viva64.com/ru/a/0004/
- 64-битные уроки. Урок 13. Паттерн 5. Адресная арифметика.
0