gpt4 book ai didi

c - 在编译时连接一个链表

转载 作者:太空宇宙 更新时间:2023-11-03 23:54:18 25 4
gpt4 key购买 nike

考虑一个表示单向链表中条目的 C 结构。它包含指向一些任意数据的指针、该数据的大小以及查找下一个条目的方法

typedef struct{
unsigned char *data
unsigned char dataSize
unsigned char nextEntry
} Entry;

接下来,考虑以下条目集合及其代表的数据:

unsigned char dataA[3];
unsigned char dataB[16];
unsigned char dataC[17];

Entry entryA = {dataA, sizeof(dataA), 3}; //It's important for "3" to match up with the index of entryB once it's put into MasterList below.
Entry entryB = {dataB, sizeof(dataB), 4}; //Likewise
Entry entryC = {dataC, sizeof(dataC), 0}; //0 terminates the linked list
Entry emptyEntry = {(void*)0, 0, 0};

Entry MasterList[8] = {
entryA, //Index 0 - Contains dataA and points to Index 3 as the next Entry in a linked list
emptyEntry, //Index 1 - Unused (or used for something else)
emptyEntry, //Index 2 - Unused
entryB, //Index 3 - Contains dataB and points to Index 5 as the next Entry in a linked list
entryC, //Index 4 - Contains dataC and terminates the linked list
emptyEntry, //Index 5 - Unused
emptyEntry, //Index 6 - Unused
emptyEntry};//Index 7 - Unused

我的问题:你能想出一种在编译时自动计算出“nextEntry”值的方法吗?现在,如果有人打乱 MasterList 中条目的顺序或添加一些其他数据并抵消一些条目,则存在巨大的错误潜力。我们通过单元测试或集成测试捕获所有错误,但不可避免的是,对 MasterList 的任何更改最终都会被检查两次。一次有人编辑它,第二次在代码测试失败时修补链表索引。

我最初的直觉是“不,那是愚蠢的”和“你为什么要尝试这个?”但我过去曾见过一些令人印象深刻的 C-Macro 魔法。我也相信任何宏观魔法都比上面的更难维护,但我认为值得一试,对吧?

澄清 - 我坚持使用 MasterList 数组(而不是正确的链表),因为信息的消费者期望它是这样的。事实上,那里还有其他信息不属于需要位于固定索引处的链表的一部分。然后,最重要的是,有这个链表数据。它是一个链表的原因是,当添加其他具有固定索引的元素时,它在某种程度上不会被推来推去。例如,如果结果证明我们需要在索引 3 处插入一个特定的字符串,则 entryB 和 entryC 可能会被推开,但仍然可以通过从链表头(固定在索引 0 处)开始来发现,并且遍历列表。

最佳答案

通过重置和使用行号:

#line 0 
#define NUM ( __LINE__ -2)
Entry MasterList[8] =
{ {dataA, sizeof(dataA), NUM }
, {(void*)0, 0, NUM }
, {(void*)0, 0, NUM }
, {dataB, sizeof(dataB), NUM }
, {dataC, sizeof(dataC), NUM }
, {(void*)0, 0, NUM }
, {(void*)0, 0, NUM }
, {(void*)0, 0, NUM }
};

gcc -E 的输出:

# 28 "index.c"
#pragma #line 0 __FILE__
# 1 "index.c"

Entry MasterList[8] =
{ {dataA, sizeof(dataA), ( 2 -2) }
, {(void*)0, 0, ( 3 -2) }
, {(void*)0, 0, ( 4 -2) }
, {dataB, sizeof(dataB), ( 5 -2) }
, {dataC, sizeof(dataC), ( 6 -2) }
, {(void*)0, 0, ( 7 -2) }
, {(void*)0, 0, ( 8 -2) }
, {(void*)0, 0, ( 9 -2) }
};

应该可以在不重置行号的情况下做到这一点。

关于c - 在编译时连接一个链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11765547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com