它失败,因为{3, 4}
,尽管它是一个有效的初始化,不是表达式(至少它是不是在C;见以下更多关于C++)。
C中的每个表达式都有一个可以通过检查表达式本身来确定的类型。 {3, 4}
可能是struct T
或int[2]
(一种数组类型)或任何其他类型中的任何一种。
C99增加了一个名为复合文字使用类似的语法来初始化,但让你指定类型的新功能,创建一个表达式:
b = (struct T){3, 4};
注意,(struct T)
是不铸造操作;它是复合文字语法的一部分。
有关复合文字的更多信息,请参阅draft C11 standard的第6.5.2.5节。
复合文字由1999 ISO C标准(C99)引入。如果你的编译器不支持C99或更好(*咳嗽*微软*咳嗽*),那么你将无法使用它们。
如果您使用C++(不要忘记是不同的语言),它不支持复合文字,但可能有其他选择。作为Potatoswatter在评论中指出,这样的:
b = T{3, 4};
是C++ 11有效(但不是在早期版本的C++语言)。这在C++标准的5.2.3节[expr.type.conf]中有介绍。
对于这个问题,这一点:
b = {3, 4};
也是有效的C++ 11语法。此表单可用于多个指定的上下文中,包括任务的右侧。这在C++标准的8.5.4节[dcl.init.list]中有介绍。
C++标准最近的一个草案是N3485。
(g ++在C++中支持C99风格的复合文字作为扩展。)
如果你坚持用C99预编译,你总是可以编写自己的初始化函数,如:
struct T init_T(int x, int y) {
struct T result;
result.x = x;
result.y = y;
return result;
}
/* ... */
struct T obj;
/* ... */
obj = init_T(3, 4);
这是额外的工作,一个恼人的量(这就是为什么C99加入复合文字),但它能完成这项工作。另一方面,在大多数情况下,使用初始化可能会更好:
struct T obj;
/* ... */
{
struct T tmp = { 3, 4 };
obj = tmp;
}
哪一个更好可能取决于您的程序的结构。
我知道这**是**欺骗:http://stackoverflow.com/q/16614045/694576 – alk
@克,这不完全是一个重复。另一个链接讲的是将一个结构赋值给一个结构体,而这个结构体只是将一个初始化程序赋值给一个结构体。 – user1952500
'b = {3,4};'不是一个初始化,而是一个赋值。前者是'T b = {3,4};'。是的,这两个是不同的野兽...... :-)初始化发生在定义过程中。在所有其他情况下,分配都会发生。 – alk