У меня есть односвязный тип списка, который выглядит следующим образом:
struct point { int x, y; };
struct point_list {
struct point value;
const struct point_list *next;
};
Я хочу статически инициализировать один из этих списков, возможно, с несколькими десятками записей. Я хочу написать по одному элементу в строке с постоянным отступом, чтобы упростить редактирование списка.
Пока лучшее, что я придумал, это:
const struct point_list *const my_list =
&(const struct point_list) { .value = { 1, 2 }, .next =
&(const struct point_list) { .value = { 3, 4 }, .next =
&(const struct point_list) { .value = { 5, 6 }, .next =
NULL
}}};
Но Недостатки:
- Когда я добавляю или удаляю элементы, мне нужно обновить количество закрывающих скобок в последней строке.
- Может быть трудно убедить средство форматирования кода в сохраняйте этот стиль.
Есть ли лучший способ?
Если бы у нас были рекурсивные макросы, возможно, что-то подобное могло бы сработать:
const struct point_list *const my_list = POINT_LIST(
((struct point) { 1, 2 }),
((struct point) { 3, 4 }),
((struct point) { 5, 6 }),
);
Если бы мы могли запустить код во время компиляции, может быть, что-то вроде этого может работать:
#define array_length(X) (sizeof(X) / sizeof(X[0]))
constexpr const struct point_list *array_to_list(size_t length, struct point *values) { ... }
const struct point my_array[] = {
{ 1, 2 },
{ 3, 4 },
{ 5, 6 },
};
const struct point_list *const my_list = array_to_list(array_length(my_array), my_array);