Необычная инициализация массива
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 шт):
Тут обращаешься к массиву по индексу, просто этот массив имеет значения только в индексах 200,404,405,501, а в остальных NULL(но я бы не был уверен что там всегда NULL)
Такая инициализация массивов разрешена начиная с 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. Все вот так просто.