在C中参考命名的结构成员直接初始化或分配变量数组的结构成员?

Posted

技术标签:

【中文标题】在C中参考命名的结构成员直接初始化或分配变量数组的结构成员?【英文标题】:Initializing or assigning struct members of variable array directly, with reference to named struct members, in C? 【发布时间】:2020-04-21 12:21:28 【问题描述】:

在关于 SO 和其他地方的类似问题中,在这种情况下讨论的唯一解决方案是使用数组表示法初始化结构数组,而不是使用结构成员的点名。我最接近我想要的是使用以下代码:

int texturesCount = 2;
struct textureParams textures[texturesCount];
struct textureParams textures0 =   
                                        .textureFormat = textureFormat,
                                        .textureAccess = textureAccess,
                                        .srcrect = .x = 0, .y = 0, .w = 50, .h = 50,
                                        .dstrect = .x = 0, .y = 500, .w = 50, .h = 50,
                                        .r = 255,
                                        .g = 0,
                                        .b = 0,
                                        .a = 0,
                                    ;
struct textureParams textures1 =   
                                        .textureFormat = textureFormat,
                                        .textureAccess = textureAccess,
                                        .srcrect = .x = 0, .y = 0, .w = 20, .h = 20,
                                        .dstrect = .x = 10, .y = 100, .w = 20, .h = 20,
                                        .r = 0,
                                        .g = 255,
                                        .b = 0,
                                        .a = 0,
                                    ;
textures[0] = textures0;
textures[1] = textures1;

有没有办法做到这一点 - 参考命名的结构成员创建数组的结构成员 - 但不创建临时变量 texture0texture1

【问题讨论】:

【参考方案1】:

例如,如果您要创建一个 int 数组,您可以像这样初始化它:

int arr[3] =  3, 4, 5 ;

在你的情况下是一样的,只是它是一个结构数组,每个初始化器都是一个结构初始化器:

struct textureParams textures[texturesCount] = 
    
        .textureFormat = textureFormat,
        .textureAccess = textureAccess,
        .srcrect = .x = 0, .y = 0, .w = 50, .h = 50,
        .dstrect = .x = 0, .y = 500, .w = 50, .h = 50,
        .r = 255,
        .g = 0,
        .b = 0,
        .a = 0,
    ,
    
        .textureFormat = textureFormat,
        .textureAccess = textureAccess,
        .srcrect = .x = 0, .y = 0, .w = 20, .h = 20,
        .dstrect = .x = 10, .y = 100, .w = 20, .h = 20,
        .r = 0,
        .g = 255,
        .b = 0,
        .a = 0,
    
;

【讨论】:

谢谢,但 GCC 抛出“错误:可变大小的对象可能未初始化 struct textureParams textures[texturesCount] = " @Theod'Or 您需要将数组大小设为编译时间常数。您可以通过将 texturesCount 更改为 #define 宏而不是变量来做到这一点。 @Theod'Or 一个变长数组(无论类型如何)根本无法初始化,因为它的大小在编译时是未知的。 噢!我刚刚意识到它不必是可变的 - 现在从代码中看起来很明显。已接受答案,再次感谢!【参考方案2】:

是的,您可以使用复合文字直接分配给数组的成员:

    int texturesCount = 2;
    struct textureParams textures[texturesCount];

    textures[0] = (struct textureParams) 
            .textureFormat = textureFormat,
            .textureAccess = textureAccess,
            .srcrect = .x = 0, .y = 0, .w = 50, .h = 50,
            .dstrect = .x = 0, .y = 500, .w = 50, .h = 50,
            .r = 255,
            .g = 0,
            .b = 0,
            .a = 0,
    ;
    textures[1] = (struct textureParams) 
            .textureFormat = textureFormat,
            .textureAccess = textureAccess,
            .srcrect = .x = 0, .y = 0, .w = 20, .h = 20,
            .dstrect = .x = 0, .y = 100, .w = 20, .h = 20,
            .r = 0,
            .g = 255,
            .b = 0,
            .a = 0,
    ;

【讨论】:

真的有必要转换成(struct textureParams)吗? @MiCo 它与铸造相似,但不是铸造。它被称为复合文字。它提供了一个未命名的对象。 Cast 运算符不提供对象。是的,有必要指定一个 struct 文字。请注意,它不是初始化,而是赋值。 哇,每天都学新东西!如果我没有意识到数组不需要是可变的,这将是我正在寻找的答案。我是 K&R2 旧书的粉丝,它只谈论“复合语句”。 “复合文字”是同一事物还是后来的发明? @Theod'Or 复合文字由 C99 标准引入。所以,是的,后来的发明。 @LxerLx:非常感谢您的提示。我以前不知道这些“复合文字”,我成功地尝试了它们。是的:没有指示符,它不会编译。

以上是关于在C中参考命名的结构成员直接初始化或分配变量数组的结构成员?的主要内容,如果未能解决你的问题,请参考以下文章

C中结构体内有一个成员是二维数组,可以直接赋值另一个一维数组吗?

仅初始化结构或数组的前 n 个成员

c语言怎么结构数据初始化?

c语言中,系统为结构类型变量所分配的内存空间大小如何确定?

在C中为结构指针数组成员分配地址

C/C++ 学习笔记:结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法