什么是标记结构初始化语法?

时间:2010-06-10 15:56:57

标签: c syntax linux-kernel

struct file_operations scull_fops = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
.ioctl = scull_ioctl,
.open = scull_open,
.release = scull_release,
};
  

此声明使用标准C.   标记结构初始化   语法。

有人可以详细说明吗?

3 个答案:

答案 0 :(得分:79)

在“传统”ANSI C语言(C89 / 90)中使用聚合初始值设定项({}中的初始值设定项)时,必须按顺序为每个结构成员提供单独的初始值设定项,从第一个开始。例如

struct S { int a, b, c, d; };

struct S s = { 1, 2, 3, 4 };
/* 1 for `s.a`, 2 for `s.b` and so on... */

您无需为所有成员指定初始值设定项,即您可以随时停止(其余成员将进行零初始化)。

如果由于某种原因你只关心显式初始化结构的第三个成员,你必须为第一个和第二个成员提供“虚拟”显式初始化器(只是为了达到所需的第三个)

/* We only care to explicitly initialize `s.c` */
struct S s = { 0, 0, 3 };
/* but we have to explicitly initialize `s.a` and `s.b` as well */

或完全放弃特定初始化(可能用通用= { 0 }替换它)并使用后续分配给特定成员

struct S s = { 0 };
s.c = 3;

这种基于任务的方法的一个显着好处是它独立于c声明中成员struct S的位置。

C语言的新规范(C99)允许您通过在{}

中提供所需的成员名称来使用“已标记的”初始值设定项
struct S s = { .c = 3 };

这样您只需显式初始化所需的成员(并让编译器对其余成员进行零初始化)。这不仅可以节省一些输入,还可以使聚合初始值设定项与结构类型声明中指定成员的顺序无关。

您可能知道,聚合初始化程序也可以与数组一起使用。 C99也支持使用数组进行“标记”初始化。以下示例说明了“数组”中“标签”的外观如下所示

int a[10] = { [5] = 3 };
/* `a[5]` is initialized with 3, the rest of `a` is zero-initialized */

值得注意的是C语言继续坚持聚合初始化的“全有或全无”方法:如果为结构或数组的一个(或某些)成员指定显式初始化器,整个聚合被初始化,没有显式初始化器的成员被零初始化。

答案 1 :(得分:4)

您正在使用结构成员的名称来初始化结构。即每个成员的初始化都用该成员的名字“标记”。

答案 2 :(得分:1)

关于这种类型的初始化值得一提的另一个好处是,它允许重新排序结构成员,在某些情况下,可以通过在同一硬件高速缓存行中放置指向经常访问的成员的指针来提高性能。 / p>