Программирование. Принципы и практика использования C++ Исправленное издание, стр. 246
Этот указатель можно индексировать и разыменовывать.
*p =7;p[2] = 6;p[–3] = 9;Теперь ситуация выглядит следующим образом.

Иначе говоря, мы можем индексировать указатель с помощью как положительных, так и отрицательных чисел. Поскольку результаты не выходят за пределы допустимого диапазона, эти выражения являются правильными. Однако выход на пределы допустимого диапазона является незаконным (аналогично массивам, размещенным в свободной памяти; см. раздел 17.4.3). Как правило, выход за пределы массива компилятором не распознается и (рано или поздно) приводит к катастрофе.
Если указатель ссылается на элемент внутри массива, то для его переноса на другой элемент можно использовать операции сложения и вычитания. Рассмотрим пример.
p += 2; // переносим указатель p на два элемента вправоИтак, приходим к следующей ситуации.

Аналогично,
p –= 5; // переносим указатель p на пять элементов вправоВ итоге получим следующее.

+–+=–=p += 1000; // абсурд: p ссылается на массив, содержащий // только 10 чиселdouble d = *p; // незаконно: возможно неправильное значение // (совершенно непредсказуемое)*p = 12.34; // незаконно: можно задеть неизвестные данныеК сожалению, не все серьезные ошибки, связанные с арифметикой указателей, легко обнаружить. Лучше всего просто избегать использования арифметики указателей.
Наиболее распространенным использованием арифметик указателей является инкрементация указателя (с помощью оператора
++––for (double* p = &ad[0]; p<&ad[10]; ++p) cout << *p << '\n';И в обратном порядке:
for (double* p = &ad[9]; p>=&ad[0]; ––p) cout << *p << '\n';Это использование арифметики указателей не слишком широко распространено. Однако, по нашему мнению, последний (“обратный”) пример небезопасен. Почему
&ad[9]&ad[10]>=>vectorОтметим, что в большинстве реальных программ арифметика указателей связана с передачей указателя в качестве аргумента функции. В этом случае компилятор не знает, на сколько элементов ссылается указатель, и вы должны следить за этим сами. Этой ситуации необходимо избегать всеми силами.
Почему в языке C++ вообще разрешена арифметика указателей? Ведь это так хлопотно и не дает ничего нового по сравнению с тем, что можно сделать с помощью индексирования. Рассмотрим пример.
double* p1 = &ad[0];double* p2 = p1+7;double* p3 = &p1[7];if (p2 != p3) cout << "impossible!\n";
18.5.2. Указатели и массивы
char ch[100];Размер массива
chsizeof(ch)char* p = ch;Здесь указатель
p&ch[0]sizeof(p)strlen()int strlen(const char* p) // аналогична стандартной // функции strlen(){ int count = 0; while (*p) { ++count; ++p; } return count;}Теперь можем вызвать ее как с аргументом
strlen(ch)strlen(&ch[0]