Co oznaczają nawiasy kwadratowe w inicjalizacji tablicy w C?

85
static uint8_t togglecode[256] = {
    [0x3A] CAPSLOCK,
    [0x45] NUMLOCK,
    [0x46] SCROLLLOCK
};

Jakie to ma znaczenie [0x3A]? Nauczyłem się tylko takich stwierdzeń jakint a[2] = {1, 2};

akirast
źródło
Najprawdopodobniej jest to rozszerzenie kompilatora, które pozwala zainicjować określone wpisy tablicy (przy podanych indeksach) bez wypełniania reszty.
Alexey Frunze

Odpowiedzi:

81

Oznacza to zainicjowanie n-tego elementu tablicy. Podany przez Ciebie przykład będzie oznaczał, że:

togglecode[0x3A] == CAPSLOCK
togglecode[0x45] == NUMLOCK
togglecode[0x46] == SCROLLLOCK

Są one nazywane „wyznaczonymi inicjatorami” i są w rzeczywistości częścią standardu C99. Jednak składnia bez rozszerzenia =nie jest. Z tej strony:

Alternatywną składnią tego, która była przestarzała od czasu GCC 2.5, ale GCC nadal akceptuje, jest zapisanie [index]przed wartością elementu, bez =.

huon
źródło
41

Zgodnie z dokumentacją GCC jest to zgodne z ISO C99. Nazywają to „Wyznaczonymi inicjatorami”:

Aby określić indeks tablicy, napisz „[indeks] =” przed wartością elementu. Na przykład,

 int a[6] = { [4] = 29, [2] = 15 };

jest równa

 int a[6] = { 0, 0, 15, 0, 29, 0 };

Nigdy wcześniej nie widziałem tej składni, ale właśnie skompilowałem ją za pomocą gcc 4.4.5, z -Wall. Skompilował się pomyślnie i nie dał żadnych ostrzeżeń.

Jak widać na tym przykładzie, umożliwia inicjalizację określonych elementów tablicy, pozostawiając inne nietknięte.

Jonathon Reinhart
źródło
15

Zostało to wprowadzone w C99 i nazywa się wyznaczonym inicjatorem .

Zasadniczo pozwala ustawić określone wartości w tablicy, a pozostałe pozostawione jako domyślne.

W tym konkretnym przypadku indeksy tablicy to kody skanowania klawiatury. 0x3ato kod skanowania z zestawu nr 1 (patrz sekcja 10.6) dla CapsLockklucza, 0x45to NumLocki 0x46 to ScrollLock.

W pierwszym linku powyżej stwierdza, że:

int a[6] = { [4] = 29, [2] = 15 };

jest równa:

int a[6] = { 0, 0, 15, 0, 29, 0 };

Co ciekawe, chociaż link stwierdza, że =jest to konieczne, nie wydaje się, aby tak było w tym przypadku.

paxdiablo
źródło
13

Jest to (blisko) składnia wyznaczonych inicjatorów , funkcja C99.

Zasadniczo inicjalizuje na przykład części tablicy;

int aa[4] = { [2] = 3, [1] = 6 };

Intializuje drugą wartość tablicy na 6, a trzecią na 3.

W twoim przypadku przesunięcia tablicy są w formacie szesnastkowym (0x3a), co inicjalizuje 58-ty element tablicy do wartości CAPSLOCK, która prawdopodobnie jest zdefiniowana w kodzie powyżej kodu, który pokazujesz.

Wersja w twoim kodzie bez rozszerzenia =wydaje się być rozszerzeniem specyficznym dla gcc.

Joachim Isaksson
źródło