Необычная инициализация массива

enum http_status {
    HTTP_OK = 200,
    HTTP_NOT_FOUND = 404,
    HTTP_METHOD_NOT_ALLOWED = 405,
    HTTP_INTERNAL_SERVER_ERROR = 501,
};

static const char *status2str(enum http_status status)
{
    const char *strings[] = {
        [HTTP_OK] = "Ok",
        [HTTP_NOT_FOUND] = "Not found",
        [HTTP_METHOD_NOT_ALLOWED] = "Method not allowed",
        [HTTP_INTERNAL_SERVER_ERROR] = "Internal server error",
    };
    return strings[status];
}

В функцию поступает число, как я получаю на выходе указатель на строку? Вот поступает число 200 в эту функцию, на выходе получаю указатель на строку "Ok". Не могу понять как это работает. Как работает такое обращение к массиву?

Что делает эта запись [HTTP_OK] = "Ok", что я могу обратиться к ней не по индексам, как привык делать, а по значению. Своего рода словарь получается.


Ответы (2 шт):

Автор решения: eri

Тут обращаешься к массиву по индексу, просто этот массив имеет значения только в индексах 200,404,405,501, а в остальных NULL(но я бы не был уверен что там всегда NULL)

→ Ссылка
Автор решения: eanmos

Такая инициализация массивов разрешена начиная с C99. Выражение [HTTP_OK] называется designator. Элемент массива с индексом HTTP_OK будет хранить строковой литерал "Ok", элемент с индексом HTTP_NOT_FOUND — строковой литерал "Not found" и так далее. Неинициализированные элементы будут иметь значение NULL:

strings = {
      0  NULL,
    ...  NULL,
    200  HTTP_OK,
    201  NULL,
    ...  NULL,
    404  HTTP_NOT_FOUND,
    405  HTTP_METHOD_NOT_ALLOWED,
    406  NULL,
    ...  NULL,
    501  HTTP_INTERNAL_SERVER_ERROR
}

Константа HTTP_OK и другие — это т. н. константы перечисления (англ. enumeration constants) — обычные числа типа int, поэтому когда мы пишем strings[HTTP_OK], то обращаемся к элементу с индексом 200. Все вот так просто.

→ Ссылка