Coś w tym jest dość prosty do sprawdzenia (a):
#include <stdio.h>
int main (void) {
int a[2][3][4][5];
// Ignore incorrect format specifiers for now.
printf ("%d\n", sizeof(int));
printf ("%d\n", &(a[0][0][0][0]));
printf ("%d\n", &(a[1][1][1][1]));
printf ("%d\n", (int)&(a[1][1][1][1])
- (int)&(a[0][0][0][0])
+ 1000);
return 0;
}
i wyjście to:
4
2665056
2665400
1344
Note konwersje tych wskaźników do int
wartości w tym końcowym printf
. Bez tego, 1000
będzie skalowany jako int *
, podając niewłaściwą wartość.
Tak, tak, ostatecznie, twoje rozumowanie jest poprawne.
(a) To nie zawsze przypadek, ponieważ niektóre aspekty języka C mogą różnić się w poprzek wdrożeń (zachowanie implementacji określony) lub w jakikolwiek sposób jest chcą (niezdefiniowane zachowanie).
Szczęśliwie, układ tablic jest podano szczegółowo w normie, w C11 6.5.2.1 Array subscripting
:
2/Wyrażenie przyrostek następnie wyrażeniem w nawiasach kwadratowych []
jest indeksowana oznaczenie elementu tablicy obiekt. Definicja operatora indeksu dolnego jest taka, że E1[E2]
jest identyczna z. Ze względu na zasady konwersji, które stosuje się do binarnego +
operatora, jeśli E1
Przedmiotem tablica (równoważnie, wskaźnik do pierwotnego elementu obiektu tablicy) i E2
jest liczbą całkowitą, E1[E2]
oznacza element E2-th
z E1
(licząc od zera).
3/Kolejni operatorzy indeksów podrzędnych wyznaczają element wielowymiarowego obiektu tablicowego. Jeśli E
jest tablicą n-wymiarową (n> = 2) o wymiarach i * j * ... * k
, to E
(używane jako inne niż l-wartość) jest konwertowane na wskaźnik na tablicę (n-1) o wymiarach j * ... * k
.Jeśli jednoargumentowy operator *
zostanie zastosowany do tego wskaźnika jawnie lub niejawnie w wyniku indeksowania, wynikiem jest tablica odniesienia (n-1), która sama jest przekształcana na wskaźnik, jeśli jest używana jako inna niż l-wartość. Wynika z tego, że tablice są przechowywane w kolejności rzędowej (ostatni indeks zmienia się najszybciej).
Brzmi nieźle. – JS1