为什么可以';我们不能在C中多次初始化一个结构吗?
为什么这在C中是非法的?将p重新初始化为不同的posn有什么问题?同样的效果也可以通过单独更改字段值来实现,所以我不明白为什么不能用p={1,2}一步完成为什么可以';我们不能在C中多次初始化一个结构吗?,c,C,为什么这在C中是非法的?将p重新初始化为不同的posn有什么问题?同样的效果也可以通过单独更改字段值来实现,所以我不明白为什么不能用p={1,2}一步完成 struct posn { int x; int y; }; int main() { struct posn p = {3, 4}; p = {1, 2}; //Causes error // must do p.x = 1; p.y = 2; return 0; } 这并不完全正确,您不
struct posn {
int x;
int y;
};
int main() {
struct posn p = {3, 4};
p = {1, 2}; //Causes error
// must do p.x = 1; p.y = 2;
return 0;
}
这并不完全正确,您不能使用初始值设定项列表,但您当然可以随时初始化或更精确地更改结构的成员,请尝试以下操作
p.x = 1;
p.y = 2;
初始值设定项列表只能是声明的一部分。您可以使用复合文字。比如说
#include <stdio.h>
struct posn
{
int x;
int y;
};
int main(void)
{
struct posn p = { 3, 4 };
p = ( struct posn ){ 1, 2 };
printf( "p.x = %d, p.y = %d\n", p.x, p.y );
return 0;
}
这是因为与数组相对的结构具有复制赋值运算符。
但是,您可以在结构中封装数组,并使用相同的技巧重新分配数组
这里有一个例子
#include <stdio.h>
struct posn
{
int a[2];
};
int main(void)
{
struct posn p = { { 3, 4 } };
p = ( struct posn ){ { 1, 2 } };
printf( "p.a[0] = %d, p.a[1] = %d\n", p.a[0], p.a[1] );
return 0;
}
#包括
结构posn
{
int a[2];
};
内部主(空)
{
结构posnp={3,4};
p=(结构posn){{1,2};
printf(“p.a[0]=%d,p.a[1]=%d\n”,p.a[0],p.a[1]);
返回0;
}
这样看起来就像
,p={1,2}
必须是一个表达式。但是什么类型的呢?它可以是{1,2}
,或者int[2]
,或者其他很多东西struct{int a;short s;}
{}
括号中的初始值设定项:
p = (struct posn){1, 2};
初始值设定项列表只能在变量声明中使用。“为什么”通常不是正确的问题(如果只是“因为”…)您正在寻找这个问题吗?我试着不告诉OP,那是纯C吗?我想它可能是C++specific@abelenky这是一个纯C特性。在C++中没有复合文字,这正是我要问的。为什么我不能用{1,2}创建一个新的posn,并用p={1,2}给它赋值p@TanWang你可以从Vlad的回答中看到这一点,但在我看来,这不会带来任何好处,如果你不太小心,它可能会导致问题,所以如果你是初学者,不要使用它。我不喜欢,因为演员阵容可能会导致问题。@iharob:好奇:复合文字会导致什么问题?@mafso如果你不够小心,你会这样做
struct posn p;p=(结构posn){1}代码>意外地,那么就很难找到问题了。@iharob:这看起来并不比struct posn p={1}更危险代码>。我通常尽可能避免强制转换,但复合文字不是强制转换,我看不出强制转换有任何缺点。(考虑const char*foo;
,一个cast可以(可能是意外地)删除const((int*)foo
),一个复合文本不能((int*){foo}
不编译)等等)复合文本触发与赋值或初始化完全相同的隐式转换,一个演员几乎可以触发每一次转换。谢谢你的解释;我没有意识到大括号可以代表posn以外的东西。
p = (struct posn){1, 2};