结构中的结构数组 typedef 显示不完整的数据

Struct array typedef in struct shows incomplete data

我在处理一段代码时遇到问题,其中的 typedef 数组是由结构创建的。然后在另一个结构中使用该 typedef。
在函数中接收 typedef 并使用其中的 typedef 初始化结构时,我只获取数组中第一个元素的数据。

下面是我目前得到的一个简化示例。

struct simple_struct {
    double a;
};

typedef struct simple_struct arr_typedef[2];

struct struct_with_typedef {
    const arr_typedef typedef_arr;
};

void foo(const arr_typedef arg_s) {
    struct struct_with_typedef test = {
        *arg_s
    };

    int i;
    for (i = 0; i < 2; i++) {
        printf("value: %f \n", test.typedef_arr[i].a);
    }
}

int main(int argc, char* argv[]) {
    arr_typedef d_test = { {1}, {2} };
    foo(d_test);

    return 1;
}

编译时,使用 gcc 4.4 和 运行 我看到以下输出:

~/public > ./test                  
value: 1.000000 
value: 0.000000

有人可以解释为什么第二项的值不可用吗?
如果我遗漏了取消引用,我在编译时会出现以下错误,我也没有得到:

test.c:82: error: incompatible types when initializing type 'double' using type 'const struct simple_struct *'


我删除了 typedef,结果仍然存在。有点理解确实给出了一个初始化值。但是struct里面只有一个成员,还是后台展开的?
如果是这样,您将如何初始化这两个值?

struct simple_struct {
    double a;
};

struct struct_with_arr {
    const struct simple_struct struct_arr[2];
};

void foo(const struct simple_struct arg_s[2]) {
    struct struct_with_arr test = {{*arg_s}};

    int i;
    for (i = 0; i < 2; i++) {
        printf("value: %f \n", test.struct_arr[i].a);
    }
}

int main(int argc, char* argv[]) {
    struct simple_struct d_test[2] = { {1}, {2} };
    foo(d_test);

    return 1;
}

在此声明中

struct struct_with_typedef test = {
    *arg_s
};

使用 struct simple_struct 类型的对象来初始化 const arr_typedef.

类型的数组

首先,您需要将初始值设定项括在大括号中,如果您愿意,还需要为数组的第二个元素添加初始值设定项。

初始化数组的正确方法如下

#include <stdio.h>

struct simple_struct 
{
    double a;
};

typedef struct simple_struct arr_typedef[2];

struct struct_with_typedef 
{
    const arr_typedef typedef_arr;
};

void foo( const arr_typedef arg_s ) 
{
    struct struct_with_typedef test = 
    {
        { arg_s[0], arg_s[1] }
    };

    for ( int i = 0; i < 2; i++ ) 
    {
        printf("value: %f \n", test.typedef_arr[i].a);
    }
}

int main( void ) 
{
    arr_typedef d_test = { {1}, {2} };
    foo(d_test);

    return 0;
}

程序输出为

value: 1.000000 
value: 2.000000 

你也可以通过以下方式编写初始化程序

struct struct_with_typedef test = 
{
    { *arg_s, *( arg_s + 1 ) }
};

考虑到用作初始值设定项表达式的数组指示符被隐式转换为指向其第一个元素的指针。取消引用指针,您将获得第一个元素本身。

C 中没有用于使用表示要从中复制值的另一个数组的单个初始化程序来初始化数组的语法。

要修复您的代码,您可以执行以下选项之一:

  1. 列出成员:struct struct_with_arr test = {{arg_s[0], arg_s[1]}};
  2. 更改函数以接受 struct struct_with_arr 作为参数类型,在这种情况下您可以使用 struct struct_with_arr test = arg;
  3. 不带初始值设定项的复制:struct struct_with_arr test; memcpy(&test.struct_arr, arg_s, sizeof test.struct_arr);。 (实际上,您不能使用此选项,因为您已将结构元素定义为 const ... 在我看来,这首先不是一个好主意)

为了完整起见,我将提及代码:

struct struct_with_arr foo = *(struct struct_with_arr *)arg_s;

这是技术上未定义的行为之一(如果参数源实际上不是 struct_with_arr),但可能适用于任何存在的实际编译器。我的建议是不要这样做。