Почему в двух приведенных выше выходных данных сначала проверяется 4-й индекс, а во втором - 2-й индекс?
Это не совсем близко к описанию происходящего.
Чтобы понять, что происходит, запишите примеры в их фактическом значении
int z[][3] = { 1, 2, 3, 4, 5, 6 };
printf("\n**(z+1): %d", **(z + 1));
на самом деле
int z[][3] = { {1, 2, 3}, {4, 5, 6} };
printf("\n**(z+1): %d", **(z + 1));
где z[0]
- это массив из трех элементов, инициализированный с помощью {1, 2, 3}
и z[1]
- это массив из трех элементов, инициализированных с помощью {4,5,6}
.
В этом z + 1
равно &z[0] + 1
, что равно &z[1]
(адрес массива из трех int
). Итак, *(z+1)
- это (ссылка на) z[1]
(массив из трех элементов), а **(z+1)
- это z[1][0]
. Поскольку z[1]
- это массив, инициализированный как элементы {4,5,6}
, z[1][0]
- это первый элемент этого массива. Он имеет значение 4
.
Для сравнения:
char y[][3] = { "A", "F", "G", "J", "M", "P" };
printf("\n**(y+1): %c", **(y+1));
каждый из строковых литералов инициализируется как массив из двух элементов, например, "A"
инициализируется как {'A', '\0'}
.
Теперь y
- это массив массивов из трех char
. Если массиву из трех элементов задан инициализатор с двумя char
, как здесь, значения, которые не инициализированы явно, инициализируются нулем. Итак,
char y[][3] = { "A", "F", "G", "J", "M", "P" };
эквивалентно
char y[][3] = { {'A', '\0', '\0'}, {'F', '\0', '\0'}, {'G', '\0', '\0'}, {'J', '\0', '\0'}, {'M', '\0', '\0'}, {'P', '\0', '\0'}};
Итак, y
- это массив из шести элементов, каждый из которых представляет собой массив из трех char
.
Используя тот же лог c, что и в обсуждении z
выше, y + 1
равно &y[1]
, где y[1]
- это массив из трех char
, который инициализируется как {'F', '\0', '\0'}
. Итак, *(y + 1)
- это (ссылка на) y[1]
, а **(y + 1)
- y[1][0]
. Это значение 'F'
.