我的教授给了我一些我以前从未见过的代码。我正在努力做尽职调查,然后在我的教授的低级别的东西上打扰(并且可能会惹恼我自己)。
首先定义一个结构。
struct entry {
char *lexptr;
int token;
};
然后在另一点,定义并初始化数组。
struct entry keywords[] = {
"div", DIV,
"mod", MOD,
0 , 0
};
其中DIV
和MOD
是#define
指令。令我惊讶的是,一切都在编译和运行。
就个人而言,我会做一些像新手一样的新手。
struct entry keywords[3];
keywords[0]->lexptr="div";
keywords[0]->token=DIV;
//and so on
我的第一个问题是,init方法如何像它一样工作?我最好的猜测是,数组的地址位置与结构中定义的元素的顺序相匹配。因此,元素定义{"div", DIV,"mod", MOD, 0 , 0};
很适合地址级别的entry
的三个元素。
我的第二个问题是,这是正常的吗?为什么这种方式与我的sliglty更可读,更冗长,初始化数组的版本?第一种方法有什么优点吗?
答案 0 :(得分:5)
最好是写成:
const struct entry keywords[] =
{
{ "div", DIV },
{ "mod", MOD },
{ 0, 0 }
};
在每个子结构周围使用大括号(在结构定义和数组中指针应该是const
),但这是你初始化静态数组的方法结构,它也可用于初始化本地数组。
此外,在C99中,您可以使用指定的初始值设定项:
const struct entry keywords[] =
{
[0] = { .lexptr = "div", .token = DIV },
[1] = { .lexptr = "mod", .token = MOD },
[2] = { .lexptr = 0, .token = 0 }
};
在这个例子中,符号没有优势(我不会使用它),但在更复杂的情况下,结构中许多字段中只有少数几个需要在每一行中初始化,指定的初始化者可能有优势。您也可以不按顺序使用初始化程序。同样,您不会在此处使用它,但如果您有条目enum
,则可以使用[ENUMX] = { ... }, [ENUMY] = { ... }, ...
而无需知道与ENUMX和ENUMY对应的数字。 (注意:我可以使用没有成员名称的索引名称,或没有索引名称的成员名称;我展示了两者以说明选项的范围。)
使用初始化比使用您显示的可执行代码更好。静态或全局数组的初始化由系统在加载程序时完成,因此它减少了执行时间,并减少了可执行文件中的代码量(两者都是可取的)。它还允许结构保持不变,因此不能在运行时更改它们。分配要求结构可以修改。
答案 1 :(得分:1)
这只是初始化结构数组的另一种方法。是的,你的初始化程序中给出的元素是按结构定义的顺序排列的。首先你有char*
(基本上是字符串),然后是int
。然后你有了下一个结构,具有相同的模式。
这只是初始化struct
甚至是数组结构的更简洁方法。
你如何写作,在一天结束时确实是一个偏好的问题。
除了显而易见的打字外,我本身并不知道任何优点。
答案 2 :(得分:1)
它不是一个神奇的记忆叠加,而是在标准中设计 - 即它将正确应对结构包装。这就是你如何初始化一系列结构:-)它很常见,只是一个品味问题。您如何编写它并没有错,我想这可能更容易阅读,因为它更明确,并且不需要结构元素排序的知识。