arr
можно более интуитивно написать так:
int arr[3][3] = {
{1,2,3},
{4,5,6},
{7,8,9},
};
*(arr+1)[1]
эквивалентно **(arr+2)
, потому что a[n]
эквивалентно *(a+n)
. arr+2
пропускает две строки, указывая на {{7,8,9}}, затем две звездочки разыменовывают первое из этих значений.
**(arr+1)
работает так же.
По определению a[b]
эквивалентно *(a + b)
.
[]
(постфикс) имеет более высокий приоритет, чем *
(префикс), поэтому *a[b]
анализируется как *(a[b])
.
*(arr+1)[1]
анализируется как *((arr+1)[1])
.
*((arr+1)[1])
эквивалентно *(*(arr+1+1))
.
*(*(arr+1+1))
уменьшается до **(arr+2)
.
**(arr+2)
эквивалентно *(arr[2])
.
*(arr[2])
эквивалентно *(arr[2]+0)
.
*(arr[2]+0)
эквивалентно arr[2][0]
.
**(arr+1)
эквивалентно *(arr[1])
.
*(arr[1])
эквивалентно *(arr[1]+0)
.
*(arr[1]+0)
эквивалентно arr[1][0]
.
Что касается фактических данных:
int arr[3][3] = {1,2,3,4,5,6,7,8,9};
немного трудно читать. Лучше:
int arr[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
В первом случае arr[2][0]
дает вам первый элемент (7
) третьего подмассива (7,8,9
), а во втором случае arr[1][0]
дает вам первый элемент (4
) второго подмассива (4,5,6
).
"возможно"? Должен быть! "интуитивно"? Правильно!