通过数组初始化结构

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)

其中DIVMOD#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更可读,更冗长,初始化数组的版本?第一种方法有什么优点吗?

Jon*_*ler 5

如果写的话可能更好:

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的数字.(注意:我可以使用没有成员名称的索引名称,或者没有索引名称的成员名称;我展示了两者以说明选项的范围.)

使用初始化比使用您显示的可执行代码更好.静态或全局数组的初始化由系统在加载程序时完成,因此它减少了执行时间,并减少了可执行文件中的代码量(两者都是可取的).它还允许结构保持不变,因此不能在运行时更改它们.分配要求结构可以修改.