Cha*_*son 1 c arrays structure
我的教授给了我一些我以前从未见过的东西的代码.我正在努力做我的尽职调查,然后我在低级别的东西上打扰(并且可能会嘲笑自己)我的教授.
首先定义一个结构.
struct entry {
char *lexptr;
int token;
};
Run Code Online (Sandbox Code Playgroud)
然后在另一点,定义并初始化数组.
struct entry keywords[] = {
"div", DIV,
"mod", MOD,
0 , 0
};
Run Code Online (Sandbox Code Playgroud)
其中DIV和MOD是#define指令.令我惊讶的是,一切都编译并运行.
就个人而言,我会做一些像新手一样的事情.
struct entry keywords[3];
keywords[0]->lexptr="div";
keywords[0]->token=DIV;
//and so on
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是,init方法如何像它一样工作?我最好的猜测是,数组的地址位置与结构中定义的元素的顺序相匹配.因此,元素定义{"div", DIV,"mod", MOD, 0 , 0};很适合entry地址级别的三个元素.
我的第二个问题是,这是正常的吗?为什么这种方式与我的sliglty更可读,更冗长,初始化数组的版本?第一种方法有什么优点吗?
如果写的话可能更好:
const struct entry keywords[] =
{
{ "div", DIV },
{ "mod", MOD },
{ 0, 0 }
};
Run Code Online (Sandbox Code Playgroud)
它使用围绕每个子结构的大括号(并且应该可以说是const结构定义中的指针以及数组上的指针),但这是你初始化静态结构数组的方法,它可以用于也初始化本地数组.
此外,在C99中,您可以使用指定的初始值设定项:
const struct entry keywords[] =
{
[0] = { .lexptr = "div", .token = DIV },
[1] = { .lexptr = "mod", .token = MOD },
[2] = { .lexptr = 0, .token = 0 }
};
Run Code Online (Sandbox Code Playgroud)
在这个例子中,符号没有优势(我不会使用它),但在更复杂的情况下,可能只需要在每一行中初始化结构中的许多字段中的一些,指定的初始化器可能有一个优势.您也可以不按顺序使用初始化程序.同样,你不会在这里使用它,但是如果你有一个enum条目,你可以使用[ENUMX] = { ... }, [ENUMY] = { ... }, ...而不需要知道对应于ENUMX和ENUMY的数字.(注意:我可以使用没有成员名称的索引名称,或者没有索引名称的成员名称;我展示了两者以说明选项的范围.)
使用初始化比使用您显示的可执行代码更好.静态或全局数组的初始化由系统在加载程序时完成,因此它减少了执行时间,并减少了可执行文件中的代码量(两者都是可取的).它还允许结构保持不变,因此不能在运行时更改它们.分配要求结构可以修改.