Was bedeuten eckige Klammern bei der Array-Initialisierung in C?

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

Was bedeutet das [0x3A]hier? Ich habe nur Aussagen wie gelerntint a[2] = {1, 2};

akirast
quelle
Höchstwahrscheinlich handelt es sich um eine Compiler-Erweiterung, mit der Sie bestimmte Array-Einträge (bei bestimmten Indizes) initialisieren können, ohne den Rest auszufüllen.
Alexey Frunze

Antworten:

81

Dies bedeutet, dass das n- te Element des Arrays initialisiert wird . Das Beispiel, das Sie gegeben haben, bedeutet Folgendes:

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

Diese werden als "designierte Initialisierer" bezeichnet und sind tatsächlich Teil des C99-Standards. Die Syntax ohne das =ist jedoch nicht. Von dieser Seite:

Eine alternative Syntax hierfür, die seit GCC 2.5 veraltet ist, aber von GCC weiterhin akzeptiert wird, besteht darin, [index]vor den Elementwert mit der Nr =.

huon
quelle
41

Laut GCC-Dokumenten ist dies ISO C99-konform. Sie bezeichnen es als "Designated Initialzers":

Um einen Array-Index anzugeben, schreiben Sie "[index] =" vor den Elementwert. Beispielsweise,

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

ist äquivalent zu

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

Ich habe diese Syntax noch nie gesehen, aber ich habe sie nur mit gcc 4.4.5 mit -Wall kompiliert. Es wurde erfolgreich kompiliert und gab keine Warnungen.

Wie Sie in diesem Beispiel sehen können, können Sie bestimmte Array-Elemente initialisieren und die anderen unberührt lassen.

Jonathon Reinhart
quelle
15

Das wurde in C99 eingeführt und wird als Designated Initialisierer bezeichnet .

Grundsätzlich können Sie bestimmte Werte in einem Array festlegen, wobei der Rest als Standard bleibt.

In diesem speziellen Fall sind die Array-Indizes die Tastatur-Scan-Codes. 0x3aist der Scan-Code in Satz 1 (siehe Abschnitt 10.6) für den CapsLockSchlüssel, 0x45ist NumLockund 0x46 ist ScrollLock.

Auf dem ersten Link oben heißt es:

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

ist äquivalent zu:

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

Interessanterweise =scheint dies hier nicht der Fall zu sein , obwohl der Link angibt , dass dies notwendig ist.

paxdiablo
quelle
13

Es ist (nahe) an der Syntax bestimmter Initialisierer , einer C99-Funktion.

Grundsätzlich werden beispielsweise Teile eines Arrays initialisiert.

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

Initialisiert den zweiten Wert des Arrays auf 6 und den dritten auf 3.

In Ihrem Fall sind die Array-Offsets zufällig hexadezimal (0x3a), wodurch das 58. Element des Arrays auf den Wert von CAPSLOCK initialisiert wird, der vermutlich im Code über dem angezeigten Code definiert ist.

Die Version in Ihrem Code ohne das =scheint eine gcc-spezifische Erweiterung zu sein.

Joachim Isaksson
quelle