Арифметика указателей — фундаментальная особенность языка C, делающая работу с памятью гибкой, но и потенциально опасной.
Арифметика указателей возникла из-за особенностей языков низкого уровня и ориентирована на работу с массивами и обработку структурированных данных напрямую в памяти. В C все указатели "знают" размер типа, на который указывают.
Многие разработчики ошибаются, думая, что при добавлении к указателю единицы адрес увеличится ровно на один байт. На самом деле увеличение происходит на sizeof(тип). При работе с разными типами данных, особенно со структурами разного размера, легко ошибиться при переходах по памяти. Также арифметика указателей не допускается с void* — это стандартная ошибка.
Все арифметические действия с указателями учитывают размер соответствующего типа, что делает операции с массивами максимально эффективными. Например:
#include <stdio.h> int arr[4] = {10, 20, 30, 40}; int *p = arr; printf("%d ", *(p + 2)); // Выведет 30
Здесь (p + 2) сдвигает указатель на 2 * sizeof(int) байта вперед, а не просто на 2 байта.
Ключевые особенности:
Можно ли выполнять операции инкрементации/декрементации с указателями на void?
Нет, стандарт C запрещает арифметику с void*. Сначала необходимо привести указатель к конкретному типу, например (char*), а уже потом выполнять арифметику.
void *vp = arr; char *cp = (char *)vp; cp++;
Что произойдет, если прибавить к указателю на структуру или массив значение, превышающее размер массива?
Это приведет к выходу за пределы допустимой области памяти (undefined behavior). C не проверяет границы массивов — ответственность на программисте.
Можно ли складывать два указателя между собой напрямую?
Нет, складывание указателей запрещено и не имеет смысла. Допустимо только вычитание двух указателей, принадлежащих одному массиву.
Молодой разработчик, работая с int массивом по указателям, сдвигал указатель на фиксированное число байтов, забыв про размер типа.
Плюсы:
Минусы:
Опытный разработчик всегда использует выражения вроде (ptr + n), доверяя компилятору масштабировать сдвиг по размеру типа.
Плюсы:
Минусы: