首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

compound literals

构造一个指定类型的未命名对象,当仅需要一次数组,结构或联合类型的变量时使用。

句法

( type ) { initializer-list }

(since C99)

其中

type

-

a type name specifying any complete object type or an array of unknown size, but not a VLA

initializer-list

-

list of initializers suitable for initialization of an object of type

说明

复合文字表达式构造由 type 指定的类型的未命名对象,并按 initializer-list 的指定进行初始化。

复合文字的类型是 type(除非 type 是一个未知大小的数组;其大小是从初始化程序列表中推导出来的,与数组初始化中一样)。

复合文字的值类别是左值(可以取其地址)。

如果复合文字出现在块范围(在这种情况下对象的生存期在封闭块的末尾结束),则复合文字评估的未命名对象具有静态存储持续时间,前提是复合文字出现在文件范围和自动存储持续时间。

注意

常量限定字符或宽字符数组类型的复合文字可能与字符串文字共享存储空间。

代码语言:javascript
复制
(const char []){"abc"} == "abc" // might be 1 or 0, implementation-defined

每个复合文字在其范围内仅创建一个对象:

代码语言:javascript
复制
int f (void)
{
    struct s {int i;} *p = 0, *q;
    int j = 0;
again:
    q = p, p = &((struct s){ j++ });
    if (j < 2) goto again; // note; if a loop were used, it would end scope here, 
                           // which would terminate the lifetime of the compound literal
                           // leaving p as a dangling pointer
    return p == q && q->i == 1; // always returns 1
}

因为复合文字是未命名的,所以复合文字不能自我引用(一个已命名的结构可以包含一个指向自身的指针)。

尽管复合文字的语法类似于强制转换,但重要的区别是,强制转换是非左值表达式,而复合文字是左值。

代码语言:javascript
复制
int *p = (int[]){2, 4}; // creates an unnamed static array of type int[2]
                        // initializes the array to the values {2, 4}
                        // creates pointer p to point at the first element of the array
const float *pc = (const float []){1e0, 1e1, 1e2}; // read-only compound literal
 
int main(void)
{
    int n = 2, *p = &n;
    p = (int [2]){*p}; // creates an unnamed automatic array of type int[2]
                       // initializes the first element to the value formerly held in *p
                       // initializes the second element to zero
                       // stores the address of the first element in p
 
    struct point {double x,y;};
    void drawline1(struct point from, struct point to);
    void drawline2(struct point *from, struct point *to);
    drawline1((struct point){.x=1, .y=1},  // creates two structs with block scope 
              (struct point){.x=3, .y=4}); // and calls drawline1, passing them by value
    drawline2(&(struct point){.x=1, .y=1},  // creates two structs with block scope 
              &(struct point){.x=3, .y=4}); // and calls drawline2, passing their addresses
}

参考

  • C11 standard (ISO/IEC 9899:2011):
    • 6.5.2.5 Compound literals (p: 85-87)
  • C99 standard (ISO/IEC 9899:1999):
    • 6.5.2.5 Compound literals (p: 75-77)

扫码关注腾讯云开发者

领取腾讯云代金券