为什么可以';我们不能在C中多次初始化一个结构吗?

为什么可以';我们不能在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; } 这并不完全正确,您不

为什么这在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;
}

这并不完全正确,您不能使用初始值设定项列表,但您当然可以随时初始化或更精确地更改结构的成员,请尝试以下操作

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> < P>这是语言的指定方式。< /P> 为了在某种程度上与C的一般设计保持一致,为了允许

p={1,2}
{1,2}
必须是一个表达式。但是什么类型的呢?它可以是
int[2]
,或者
struct{int a;short s;}
,或者其他很多东西

对于C99,可以使用一个复合文字,它显式地提到类型(从而解决了如何确定类型的问题),一个带括号的类型名,后跟
{}
括号中的初始值设定项:

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