在结构体初始化器中,点(.)表示成员的访问。

171
static struct fuse_oprations hello_oper = {
  .getattr = hello_getattr,
  .readdir = hello_readdir,
  .open    = hello_open,
  .read    = hello_read,
};

我对这段 C 语法不太理解。我甚至无法搜索,因为我不知道这种语法的名称。那是什么?


看起来像是一个结构体初始化器。 - Mysticial
8
标准化于C99,如果你使用(非常)旧的编译器,则无法起作用。 - Some programmer dude
3
最终找到了这个链接:https://dev59.com/nnRC5IYBdhLWcg3wVvct。 - Mysticial
6
很遗憾,即使按照这个标准来衡量,目前的MSVC版本也是“相当老旧的编译器”。 - Jonathan Leffler
非常奇怪,我在学习fuse教程的同时搜索了这个问题,并编写了完全相同的初始化程序。 - Keegan Jay
“Boo” to change. 这种节省打字的方式只会增加人们未来需要掌握的知识,进而导致未来 C 语言专家减少。我们需要更多的专家,而不是更少。 - kackle123
4个回答

191
这是 C99 的一个新特性,它允许您在初始化器中通过名称设置结构的特定字段。在这之前,初始化程序需要按顺序包含所有字段的值 - 当然,这仍然有效。
因此,对于以下结构:
struct demo_s {
  int     first;
  int     second;
  int     third;
};

...你可以使用

struct demo_s demo = { 1, 2, 3 };

…或者:

struct demo_s demo = { .first = 1, .second = 2, .third = 3 };

甚至可以:

struct demo_s demo = { .first = 1, .third = 3, .second = 2 };

尽管最后两个仅适用于C99。

2
点初始化在C++中也适用吗?(我需要测试一下) - Gabriel Staples
4
看起来是可以的,但仅限于 C ++20,只需查看文档即可。这是适用于C语言(从C99开始)的cppreference.com文档:https://en.cppreference.com/w/c/language/struct_initialization,以及适用于C++的文档(仅适用于C++20):https://en.cppreference.com/w/cpp/language/aggregate_initialization。 - Gabriel Staples
请注意,我刚刚尝试了使用gcc的C++中的“点初始化”类型形式,并且似乎所有版本的gcc C++都支持它,因此我敢打赌它被gcc作为gcc扩展支持,这意味着在C++20之前,我怀疑它不一定可移植到非gcc/g++编译器。话虽如此,我正在使用gcc/g++编译器,所以如果它在C++中由gcc支持,我也可以使用它。 - Gabriel Staples
在点初始化中存在一个潜在的陷阱(至少对于某些编译器而言)。 struct demo_s demo = { .first = 1, .first = 9 }; 在我的某个GCC上,这将编译而不会警告,并且first将是9。 - Renate

26

18

这被称为“指定初始化”(参见指定初始化)。一个“初始化列表”,每个 '.' 都是一个“指示器”,在这种情况下,它命名了要为 'hello_oper' 标识符指定的对象初始化的 'fuse_oprations' 结构的特定成员。


-4
整个语法被称为指定初始化器,正如COD3BOY已经提到的那样,它通常用于在声明时将结构初始化为特定或默认值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接