定义复合文字的初始化

复合文字是一个未命名的对象,它是在定义的范围内创建的。该概念最初是在 C99 标准中引入的。复合文字的一个例子是

C 标准,C11-§6.5.2.5/ 9 中的示例:

int *p = (int [2]){ 2, 4 };

p 初始化为两个 int 的未命名数组的第一个元素的地址。

复合文字是左值。未命名对象的存储持续时间是静态的(如果文字出现在文件范围内)或自动(如果文字出现在块范围内),在后一种情况下,对象的生命周期在控制离开封闭块时结束。

void `f(void)`
{
    int *p;
    /*...*/
    p = (int [2]){ *p };
    /*...*/
}

p 被分配了两个整数数组的第一个元素的地址,第一个元素具有 p 先前指向的值,第二个元素为零。[…]

这里 p 一直有效,直到块结束。

复合文字与指示符

(也来自 C11)

  struct point {
    unsigned x;
    unsigned y;
  };

  extern void drawline(struct point, struct point);

 // used somewhere like this
 drawline((struct point){.x=1, .y=1}, (struct point){.x=3, .y=4});

虚拟函数 drawline 接收两个类型为 struct point 的参数。第一个具有坐标值 x == 1y == 1,而第二个具有 x == 3y == 4

复合文字而不指定数组长度

int *p = (int []){ 1, 2, 3};  

在这种情况下,数组的大小没有指定,然后它将由初始化程序的长度决定。

复合文字,初始化程序的长度小于指定的数组大小

int *p = (int [10]){1, 2, 3}; 

复合文字的其余元素将被隐式初始化为 0

只读复合文字

请注意,复合文字是左值,因此它的元素可以修改。甲只读化合物字面可使用 const 限定符 (const int[]){1,2} 来指定。

包含任意表达式的复合文字

在函数内部,复合文字,与 C99 以来的任何初始化一样,可以有任意表达式。

void foo()
{
    int *p;
    int i = 2; j = 5;
    /*...*/
    p = (int [2]){ i+j, i*j };
    /*...*/
}