01 июля 2020

#11 Вычитание указателей


... или «А что, так можно было?»
...

Наверняка вам известно, что указатели можно вычитать друг из друга. Результатом вычитания является std::ptrdiff_t. Так вот, std::ptrdiff_t основан на целочисленном типе, способным хранить отрицательные значения. Я всегда удивлялся этому, не понимал почему. А ещё я всегда старался вычитать из большего меньшее, чтобы не получить огромное переполненное значение.



Напомню, что вычитание двух указателей возвращает разницу в адресах, способных поместить объекты того типа, на которые эти указатели ссылаются. Разница не в байтах, а объектах. Потому вычитать можно только указатели на тот же тип данных (не подойдут даже указатели производные/базовые классы), а так же нельзя вычитать указатели void*, потому что они не хранят данные об объектах.

Обратно к теме. Оказывается, можно не заморачиваться и вычитать в любую сторону. Если вычесть из меньшего большее, то получишь отрицательное значение... Для был сюрприз. Вот как-то пропустил.

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