Что означают квадратные скобки при инициализации массива в C?

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

Что здесь означает [0x3A]? Я выучил только такие утверждения, какint a[2] = {1, 2};

акираст
источник
Скорее всего, это расширение компилятора, которое позволяет вам инициализировать определенные записи массива (по заданным индексам) без заполнения остальных.
Алексей Фрунзе

Ответы:

81

Это означает инициализировать n-й элемент массива. Приведенный вами пример будет означать, что:

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

Они называются «назначенными инициализаторами» и фактически являются частью стандарта C99. Однако синтаксис без символа =- нет. С этой страницы:

Альтернативный синтаксис для этого, который устарел с GCC 2.5, но GCC все еще принимает, - это запись [index]перед значением элемента, без =.

гуон
источник
41

Согласно документам GCC, это соответствует ISO C99. Они называют это «назначенными инициаторами»:

Чтобы указать индекс массива, напишите `[index] = 'перед значением элемента. Например,

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

эквивалентно

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

Я никогда раньше не видел этого синтаксиса, но я просто скомпилировал его с помощью gcc 4.4.5 с -Wall. Он успешно компилировался и не выдавал никаких предупреждений.

Как видно из этого примера, он позволяет инициализировать определенные элементы массива, оставляя другие нетронутыми.

Джонатон Рейнхарт
источник
15

Это было введено в C99 и называется назначенным инициализатором .

Это в основном позволяет вам устанавливать определенные значения в массиве, а остальные оставлять по умолчанию.

В этом конкретном случае индексы массива являются кодами сканирования клавиатуры. 0x3a- это скан-код в наборе # 1 (см. раздел 10.6) для CapsLockключа, 0x45есть NumLockи 0x46 - ScrollLock.

В первой ссылке выше говорится, что:

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

эквивалентно:

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

Интересно, что хотя в ссылке указано, что =это необходимо, здесь, похоже, это не так.

Paxdiablo
источник
13

Это (близко к) синтаксис назначенных инициализаторов , функция C99.

По сути, он инициализирует, например, части массива;

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

Инициализирует второе значение массива до 6, а третье - до 3.

В вашем случае смещения массива указаны в шестнадцатеричном формате (0x3a), который инициализирует 58-й элемент массива значением CAPSLOCK, которое предположительно определено в коде над кодом, который вы показываете.

Версия в вашем коде без =расширения кажется специфическим для gcc.

Иоахим Исакссон
источник