C 通过数组初始化结构

C 通过数组初始化结构,c,arrays,structure,C,Arrays,Structure,我们的教授给了我一些代码和一些我以前从未见过的东西。在我打扰教授(甚至可能让自己难堪)较低层次的东西之前,我正在努力做我的尽职调查 首先定义一个结构 struct entry { char *lexptr; int token; }; 然后在另一点上,定义并初始化一个数组 struct entry keywords[] = { "div", DIV, "mod", MOD, 0 , 0 }; 其中DIV和MOD是#定义指令。令我惊讶的是,一切都在编译和运行

我们的教授给了我一些代码和一些我以前从未见过的东西。在我打扰教授(甚至可能让自己难堪)较低层次的东西之前,我正在努力做我的尽职调查

首先定义一个结构

struct entry {
    char *lexptr;
    int token;
};
然后在另一点上,定义并初始化一个数组

struct entry keywords[] = {
   "div", DIV,
   "mod", MOD,
   0 , 0
};
其中
DIV
MOD
#定义
指令。令我惊讶的是,一切都在编译和运行

就我个人而言,我会做一些新手喜欢的事情

struct entry keywords[3];

keywords[0]->lexptr="div";
keywords[0]->token=DIV;
//and so on
我的第一个问题是,init方法是如何工作的?我的最佳猜测是数组的地址位置与结构中定义的元素顺序匹配。因此元素定义
{div,div,mod,mod,0,0}
将非常适合地址级别的
条目
的三个元素


我的第二个问题是,这正常吗?为什么这种方式比我的sliglty更可读,更详细,初始化数组的版本?第一种方法有什么优点吗?

这只是初始化结构数组的另一种方法。是的,初始化器中给定的元素按照结构在中定义的顺序。首先是
char*
(本质上是字符串),然后是
int
。然后是下一个结构,具有相同的模式

这只是初始化
struct
甚至是结构数组的一种更简洁的方法

你如何写它,实际上是一个偏好的问题,在一天结束时


就其本身而言,我不知道有什么好处,除了明显的减少键入。

这只是初始化结构数组的另一种方法。是的,初始化器中给定的元素按照结构在中定义的顺序。首先是
char*
(本质上是字符串),然后是
int
。然后是下一个结构,具有相同的模式

这只是初始化
struct
甚至是结构数组的一种更简洁的方法

你如何写它,实际上是一个偏好的问题,在一天结束时


就其本身而言,我不知道有什么好处,只是打字明显少了。

如果写的是:

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


使用初始化比显示为替代的可执行代码要好得多。静态或全局数组的初始化是在加载程序时由系统完成的,因此它减少了执行时间,并减少了可执行文件中的代码量(两者都是需要的)。它还允许将结构设置为常量,以便在运行时不能更改它们。赋值要求结构可修改。

最好是将其写入:

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


使用初始化比显示为替代的可执行代码要好得多。静态或全局数组的初始化是在加载程序时由系统完成的,因此它减少了执行时间,并减少了可执行文件中的代码量(两者都是需要的)。它还允许将结构设置为常量,以便在运行时不能更改它们。赋值要求结构可修改。

与其说它是一个神奇的内存覆盖,不如说它是按照标准设计的,也就是说,它将正确处理结构打包。这只是初始化结构数组的方式:-)这很常见,只是一个品味问题。您编写它的方式也没有问题,我想这可能更容易阅读,因为它更明确,不需要了解结构元素顺序。

它不是一个神奇的内存覆盖,而是按照标准设计的,即它将正确处理结构打包。这只是你初始化一个