2010-06-10 54 views
39
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 标记结构初始化 语法。什么是标记结构初始化语法?

有人可以详细说明吗?

+4

我正在看同一本书 – 2014-01-27 00:17:54

+1

我在看同一本书到 – Lewisou 2017-09-05 02:25:28

+0

我也在看同一本书:) – 2017-10-16 10:53:45

回答

4

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

69

当您使用“传统”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; 

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

C语言(C99)的新规范,您可以通过内{}

struct S s = { .c = 3 }; 

提供所需的成员名字这样使用“标记”初始化你只明确初始化所需的成员(S)(并让编译器将其余部分初始化)。这不仅可以节省一些输入,还可以使聚合初始值设定程序独立于结构类型声明中指定成员的顺序。

您可能知道,聚合初始化器也可以用于数组。而且C99也支持使用数组进行“标记”初始化。如何在一个数组的情况下,“标签”外观是由下面的例子说明

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

值得注意的是,多一个是C语言继续坚持“全有或全无”的方式集合初始化时间:如果你为结构体或数组中的一个(或某些)成员指定一个显式初始化程序,整个聚合被初始化,并且没有显式初始化程序的成员得到零初始化。

+0

但是C++不支持标记初始化。仅支持序列样式。 – ShitalShah 2016-09-23 06:34:55

+0

@AnT + 1为伟大的答案。 – 2017-10-16 11:03:43

1

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