C:声明后初始化结构变量 [英] C: Initializing struct variables after declaration

查看:95
本文介绍了C:声明后初始化结构变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了这个问题,但无法弄清楚为什么该语言允许b = c;并失败b = {3,4}。允许后者存在问题吗?

I encountered this recently but could not figure out why the language would allow b = c; below and fail b = {3, 4}. Is there an issue with allowing the latter ?

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


推荐答案

由于 {3,4} 虽然是有效的初始化程序,但它不是表达式(至少它不在C中;有关C ++的更多信息,请参见下文)。

It fails because {3, 4}, though it's a valid initializer, is not an expression (at least it isn't in C; see below for more about C++).

C中的每个表达式的类型都可以通过检查表达式本身来确定。 {3,4} 的类型可能为 struct T int [2] (数组类型)或无数其他类型。

Every expression in C has a type that can be determined by examining the expression itself. {3, 4} could potentially be of type struct T, or int[2] (an array type), or any of a myriad of other types.

C99添加了一个名为 compoundliteral 的新功能。 em>使用与初始化程序类似的语法,但是让您指定类型并创建一个表达式:

C99 added a new feature called compound literals that use a similar syntax to initializers, but let you specify the type, creating an expression:

b = (struct T){3, 4};

请注意,(结构T) not 强制转换运算符;

Note that the (struct T) is not a cast operator; it's part of the syntax of a compound literal.

有关复合文字的更多信息,请参见草稿C11标准

For more information on compound literals, see section 6.5.2.5 of the draft C11 standard.

1999 ISO C标准(C99)。如果您的编译器不支持C99或更高版本(*咳嗽*微软*咳嗽*),那么您将无法使用它们。

Compound literals were introduced by the 1999 ISO C standard (C99). If your compiler doesn't support C99 or better (*cough*Microsoft*cough*), then you won't be able to use them.

如果使用C ++(别忘了,这是另一种语言),它不支持复合文字,但是可能有替代方法。正如Potatoswatter在评论中指出的那样:

If you're using C++ (which, don't forget, is a different language), it doesn't support compound literals, but there may be an alternative. As Potatoswatter points out in a comment, this:

b = T{3, 4};

在C ++ 11中有效(但在C ++语言的早期版本中无效)。 C ++标准的第5.2.3节[expr.type.conf]中对此进行了介绍。

is valid in C++11 (but not in earlier versions of the C++ language). This is covered in section 5.2.3 [expr.type.conf] of the C++ standard.

为此,

b = {3, 4};

也是有效的C ++ 11语法。此表格可以在许多指定的上下文中使用,包括作业的右侧。 C ++标准的8.5.4节[dcl.init.list]中对此进行了介绍。

is also valid C++11 syntax. This form can be used in a number of specified contexts, including the right side of an assignment. This is covered in section 8.5.4 [dcl.init.list] of the C++ standard.

C ++标准的最新草案是N3485。

One recent draft of the C++ standard is N3485.

(g ++在C ++中支持C99风格的复合文字作为扩展。)

(g++ supports C99-style compound literals in C++ as an extension.)

C99编译器,您始终可以编写自己的初始化函数,例如:

And if you're stuck with a pre-C99 compiler, you can always write your own initialization function, such as:

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添加复合文字的原因),但是它确实工作。另一方面,在大多数情况下,使用初始化可能会更好:

It's an annoying amount of extra work (which is why C99 added compound literals), but it does the job. On the other hand, in most cases you're probably better off using initialization:

struct T obj;
/* ... */
{
    struct T tmp = { 3, 4 };
    obj = tmp;
}

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

Which is better probably depends on how your program is structured.

这篇关于C:声明后初始化结构变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆