【发布时间】:2017-11-01 14:42:55
【问题描述】:
我想用一个宏来做这个:
typedef struct _TIMER_llist {
struct _TIMER_llist *next;
uint32_t time;
const int id;
} TIMER_llist;
TIMER_llist _timer_llists[] =
{
{ .id = 1, .next = &_timer_llists[1] },
{ .id = 2, .next = &_timer_llists[2] },
{ .id = 3, .next = &_timer_llists[3] },
{ .id = 4, .next = &_timer_llists[4] },
{ .id = 5, .next = &_timer_llists[5] },
{ .id = 6, .next = &_timer_llists[6] },
{ .id = 7, .next = &_timer_llists[7] },
{ .id = 8, .next = &_timer_llists[8] },
{ .id = 9, .next = &_timer_llists[9] },
{ .id = 10, .next = &_timer_llists[10] },
{ .id = 11, .next = &_timer_llists[11] },
{ .id = 12, .next = &_timer_llists[12] },
{ .id = 13, .next = 0 } };
//This won't work, because const .id
TIMER_llist _timer_llists[1];
void init() {
_timer_llists[0].id = 1;
_timer_llists[0].next = 0;
}
我不想为每个缓冲区条目写一行,而是使用一个
#define NUMBER_ENTRIES 13
因为这真的很不方便,如果我想做 64 个左右的条目...
不幸的是,我对 C 预处理器没有任何经验,所以我很好奇:
- 有更好的非宏解决方案
- gcc 有一个简单的方法来完成这个宏操作
此外,更多的是理论上的方面,是执行速度。 AfaIk 第一篇文章中的示例只是一个 memcpy(.data[?], _timer_llists, sizeof(_timer_llists)),而编程方法至少需要一个计数器,可能是最后一种情况的 if 语句,以及一个函数开销(好的,也许是内联的)。另一方面,这将节省 .data 中的空间。
在这种特殊情况下,我使用的是 gcc-avr,但这个问题反复出现在我的脑海中,我希望有一个通用的方法。
【问题讨论】:
-
不,没有简单的方法。 C 预处理器不支持循环或递归。有一些 X 宏技巧,但它们并不通用。
-
您可以使用 3-4 行代码以编程方式初始化数组。
-
只是出于好奇,为什么不用函数呢?
-
您可以使用 boost.preproceasor 来实现(是的,您可以将 boost.preprocessor 与 C 一起使用)。
-
一个复杂的因素是最后一个条目的空指针;它与其他的不同。任何方案都需要考虑到这一点。
标签: c c-preprocessor array-initialization