【问题标题】:Initialize struct without an assignment?在没有赋值的情况下初始化结构?
【发布时间】:2014-04-25 13:36:48
【问题描述】:

我在 Internet 上找不到这个问题的答案,所以这是我的问题:我可以定义一个结构实例而不将其分配给 C 中的局部或全局变量吗?例如:

struct A {
  int b;
}

struct A foo() {
  return struct A { .b = 42 };
}

如果这不可能:为什么?

【问题讨论】:

标签: c variables struct initialization


【解决方案1】:

是的,C99 为此提供了复合文字 (see it live):

return (struct A) {  42 } ;

draft C99 standard 部分6.5.2.5 复合文字 中介绍并说:

由带括号的类型名称后跟大括号括起来的初始值设定项列表组成的后缀表达式是复合文字。它提供了一个未命名的对象,其 值由初始化列表给出。84)

和:

复合字面量的值是由 初始化列表。如果复合文字出现在函数体之外,则该对象 具有静态存储持续时间;否则,它具有与关联的自动存储持续时间 封闭块。

并提供了几个示例,包括:

示例 3 带有名称的初始值设定项可以与复合文字组合。结构对象 使用复合文字创建的可以传递给函数,而不依赖于成员顺序:

drawline((struct point){.x=1, .y=1}, (struct point){.x=3, .y=4});

gcc 在其扩展部分也有一个 nice document,因为它支持 C99 之外的此功能以及 clang

【讨论】:

    【解决方案2】:

    是的,您可以在 C99 及更高版本中使用复合文字。

    return (struct A) { .b = 42 };
    

    你甚至可以指向它们:

    struct A *a = &(struct A) { .b = 42 };
    a->b = 43;
    

    这些文字比字符串文字“更好”,因为它们是可写的。当且仅当您在字面量的类型中包含 const 时,编译器才会将它们汇集起来。

    【讨论】:

    • 你也可以return (struct A) { 42 };.
    • 当然;虽然我认为他想使用指定的初始化程序来避免错误,以防 A 添加其他成员。
    • 是的,在这种情况下,最好是明确的。
    【解决方案3】:

    是的,从 C99 开始就有可能。那是一个复合文字。

    不过,你的语法错误。使用:

    (struct A){.b=42}
    

    (struct A){42}
    

    不过,如果没关系,请使用常量文字:

    (const struct A){.b=42}
    

    所有常量字面量都受常量池的约束(包括由于历史原因而具有 char[] 类型的字符串字面量)。
    任何函数外的常量复合字面量和复合字面量都具有静态存储持续时间,
    其余的都有自动存储时间(注意返回指针,每次都必须初始化)。

    总之,尽可能使用常量字面量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-22
      • 1970-01-01
      相关资源
      最近更新 更多