Сначала вы должны получить указатель, и вам нужно условие, когда нужно остановиться. Для этого можно использовать последний пустой указатель. Таким образом, код становится
char *str[] = { "DOG", "CAT", "RAT", NULL };
char **elem_p = str;
/* display using a pointer arthimatic */
while(*elem_p) {
printf("str: %s\n", *elem_p);
elem_p++;
}
Что вы сделали, чтобы увеличить указатель, хранящийся в первом элементе массива. Этот указатель никогда не будет слишком скоро равным нулевому указателю (если вообще будет), поэтому цикл не остановится, пока внутреннее значение этих указателей не переполнится или что-то еще не произойдет, так что он будет равен нулевому указателю. Затем вы передаете указатель на первый элемент массива в printf
(вы передаете массив, но компилятор преобразует его в указатель - см. Ниже). Printf
будет интерпретировать байты этих указателей как символы и печатать их, что приведет к распечатке мусора, если он не вылетит сразу.
Вместо этого вы хотите увеличить значение на более высокий уровень: увеличить не один элемент (указатель) массива, а указатель на сами элементы. Теперь вы не можете сделать
str++
Потому что str
- это массив. Это не указатель, даже если он может быть преобразован в указатель, который затем будет указывать на его первый элемент. Итак, мы создаем указатель, который изначально указывает на str[0]
, но снова увеличиваем его. Обратите внимание, что мы увеличиваем его после печати, поэтому мы также распечатываем первый элемент.
На самом деле, я думаю, я должен объяснить, почему вы не можете сделать str++
. Ну, str
это массив. Массив - это объект, который занимает фиксированный объем памяти. Выше массив занимает 4-кратный размер указателя на символ, 4 * sizeof(char*)
. То, что на первый взгляд выглядит как указатель, представляет собой блок элементов одного типа. Для адресации элементов компилятор может составлять указатель из массива в выражениях, который затем может использоваться для адресации элементов в массиве. Если вы сделаете str++
, компилятор создаст указатель для вас. Но этот указатель является временным, существует только на короткое время с единственной целью немедленно что-то сделать с ним, но его нельзя изменить, например, увеличивая. По этой причине мы создаем реальную переменную-указатель, которую затем можем увеличивать.