Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C:声明后初始化结构变量_C++_C - Fatal编程技术网

C++ C:声明后初始化结构变量

C++ C:声明后初始化结构变量,c++,c,C++,C,我最近遇到了这个问题,但我不明白为什么语言会允许b=c;低于并失败b={3,4}。允许后者有问题吗 struct T { int x; int y; }; int main() { T a = {1, 2}; T b; b = {3, 4}; // why does this fail ? T c = {3, 4}; b = c; // this works return 0; } 因为您没有使用正确的C99或C11“复合

我最近遇到了这个问题,但我不明白为什么语言会允许b=c;低于并失败b={3,4}。允许后者有问题吗

struct T {
    int x;
    int y;
};

int main()
{
    T a = {1, 2};
    T b;

    b = {3, 4}; // why does this fail ?

    T c = {3, 4};
    b = c; // this works

    return 0;
}

因为您没有使用正确的C99或C11“复合文字”表示法:

b = (struct T){ 3, 4 };
更多信息(除其他地方外),请参见ISO/IEC 9899:2011中的§6.5.2后缀运算符和§6.5.2.5复合文字

(类型名称){initializer list}

(类型名称){初始值设定项列表,}


它失败是因为
{3,4}
虽然是一个有效的初始值设定项,但不是一个表达式(至少它不是用C编写的;有关C++的更多信息,请参见下文)

C中的每个表达式都有一个类型,可以通过检查表达式本身来确定<代码>{3,4}可能是
struct
类型,或者
int[2]
(数组类型),或者是无数其他类型中的任何一种

C99添加了一个称为复合文字的新功能,该功能使用与初始值设定项类似的语法,但允许您指定类型,从而创建表达式:

b = (struct T){3, 4};
请注意,
(struct)
不是强制转换操作符;它是复合文字语法的一部分

有关复合文字的更多信息,请参阅本手册第6.5.2.5节

复合文字由1999年的ISO C标准(C99)引入。如果您的编译器不支持C99或更高版本(*cough*Microsoft*cough*),则您将无法使用它们

如果你使用C++(不忘,是一种不同的语言),它不支持复合文字,但可能还有其他选择。正如Potatoswatter在评论中指出的那样:

b = T{3, 4};

在C++ 11中有效(但在C++语言的早期版本中)。这在C++标准的5.2.3[Exp.Type .CONF]部分中被覆盖。

就此而言,这:

b = {3, 4};
也是有效的C++11语法。此表单可以在许多指定的上下文中使用,包括赋值的右侧。这是在C++标准的第5.5.4[DCL,init .List]的部分中所涵盖的。 <> P>一个最近的C++标准草案是N385。

(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;
}

哪个更好可能取决于程序的结构。

因为这是语言的定义。。。我不认为有什么特别的原因,除了“这使得编写编译器更难做到这一点”


<>你可以做<代码> b= t{ 3, 4 } < /> >如果你有C++ 11编译器。

在C++中,括号类型的id a a LaskStudio符号是非法的,但是<代码> t{ 3, 4 } /COD>是很有趣的。为什么编译器处理初始化和赋值的方式不同?初始化时,它似乎将RHS解释为一个结构,而在赋值时它不确定?@user1952500:正如我所说的,这是因为

{3,4}
是一个有效的初始值设定项,它从被初始化的对象获取其类型,但它不是一个有效的表达式。啊,我没有注意术语。谢谢你的回答。这不是有效的c++11语法。你必须在字体周围画上括号。这更为严重,因为在问题中使用的语法是有效的C++ 11。C++不支持复合文字。当我尝试使用一个代码“G+++STD= C++ 11—学究式< /代码>时,我得到了警告:ISO C++禁止复合文字。这就是我开始写的,但是我认为我错了,所以当我看到其他答案时就改变了它。相信你的直觉……我就知道这是个骗局:@alk,这不完全是骗局。另一个链接讨论将一个结构分配给一个结构,而这个链接只讨论将一个初始值设定项分配给一个结构不是初始化,而是赋值。前者是
tb={3,4}。是的,那两个是不同的野兽…:-)初始化发生在定义过程中。作业在所有其他情况下都会发生。所以要回答你们的问题,题目是:因为这是定义!;-)标题与内容略有不同,因此将其更改为与详细描述相匹配。它现在看起来仍然像一个dup吗?@jackcleman:正如第一句所说:它是一个C99“复合文字”。微软仍然使用C89(即24年前的版本)。@jackcleman:正如MSalters所说,由于微软C编译器是C89编译器,因此毫不奇怪地知道它不支持C99的这一功能。事实上,引用该标准(需要注意的是,旧标准,甚至不是当前标准)的原因之一是为了让那些知道MSVC存在问题的人(它是C89编译器,而不是C99或C11编译器)知道它无法使用。我并不是每次写一个需要C99或更高版本的答案时都会选择批评MS;我没有足够的时间,也不会取得任何有用的成果。