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

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

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

Ответ 1

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

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

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

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

Ответ 2

В соответствии с документами 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. Он скомпилирован успешно и не дал никаких предупреждений.

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

Ответ 3

Это было введено в 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 };

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

Ответ 4

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

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

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

Устанавливает второе значение массива на 6, а третье - на 3.

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

Версия вашего кода без =, по-видимому, является специальным расширением gcc.