12

这段代码中,一个结构体定义如下:

typedef struct
{
    int line;
    int column;
} Pos;

后来用这种方式:

Pos get_pos ( int delta )
{
    ...

    return ( Pos ){ f->line, f->column + delta };
}

该行return ( Pos ){ f->line, f->column + delta }似乎正在创建Pos具有初始化值的结构的匿名实例。这种技术叫什么,它是如何工作的?我在哪里可以了解更多信息?

4

1 回答 1

11

这称为复合文字,并记录在C 标准的第 6.5.2.5 节中。

本节摘录如下:

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

4如果类型名称指定了一个未知大小的数组,则大小由 6.7.9 中指定的初始化列表确定,复合文字的类型是完整数组类型的类型。否则(当类型名称指定对象类型时),复合文字的类型是类型名称指定的类型。无论哪种情况,结果都是左值。

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

在您的情况下,复合文字用于 a struct,但也可以为数组创建它们。第 8 段举了一个例子:

8 示例 1 文件范围定义

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

初始化p为指向两个整数数组的第一个元素,第一个元素的值为 2,第二个元素的值为 4。此复合文字中的表达式必须是常量。未命名对象具有静态存储持续时间。

另请注意,复合文字是左值,这意味着您可以获取其地址:

Pos *p = &( Pos ){ f->line, f->column + delta };

此对象具有与其作用域相关联的生命周期,这意味着一旦作用域结束,该对象将不再存在。所以不要在它超出范围后携带它的地址。

您还可以使用带有指定初始值设定项的复合文字:

return ( Pos ){ .line=f->line, .column=f->column + delta };
于 2019-02-08T04:26:11.153 回答