You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中如何将不同类型的结构体存入同一数组?

把不同结构体存入同一数组的几种实现方案

针对你提到的不同结构体(struct a/struct b/struct c)要存入同一数组的需求,结合结构体体积较大的背景,这里提供几种C语言下的可行方案:

方案1:共用体(Union)+ 类型标签(最推荐,空间高效)

这种方式通过共用体共享内存,数组元素是一个包含"类型标识"和"共用体数据"的结构体,既保证类型安全,又不会浪费过多空间(共用体的大小等于最大的那个结构体的尺寸)。

代码示例:

// 先定义类型枚举,用来标记当前存的是哪种结构体
typedef enum {
    TYPE_A,
    TYPE_B,
    TYPE_C
} StructType;

// 定义三个体积较大的结构体
struct a {
    int a_id;
    char a_data[1024];
};
struct b {
    double b_value;
    long b_timestamp;
    char b_name[256];
};
struct c {
    float c_scores[50];
    int c_count;
};

// 定义共用体,包含三个结构体
typedef union {
    struct a a_obj;
    struct b b_obj;
    struct c c_obj;
} StructUnion;

// 最终的数组元素结构体:类型标签 + 共用体数据
typedef struct {
    StructType type;
    StructUnion data;
} UniversalStruct;

// 创建可以存10个元素的数组
UniversalStruct arr[10];

// 存入示例
struct a my_a = {123, "hello struct a"};
arr[0].type = TYPE_A;
arr[0].data.a_obj = my_a;

struct b my_b = {3.14, 1690000000, "struct b test"};
arr[1].type = TYPE_B;
arr[1].data.b_obj = my_b;

// 取出示例
if (arr[0].type == TYPE_A) {
    printf("Type A ID: %d\n", arr[0].data.a_obj.a_id);
}

方案2:void指针数组(适合超大结构体,避免拷贝)

如果结构体体积非常大,拷贝整个结构体开销高,可以用void*数组存储各个结构体的地址,同时需要额外的数组记录每个元素的类型,来保证取出时能正确转换。

代码示例:

// 同样先定义类型枚举
typedef enum {
    TYPE_A,
    TYPE_B,
    TYPE_C
} StructType;

// 定义三个结构体(省略具体成员,和上面一致)
struct a { ... };
struct b { ... };
struct c { ... };

// 定义存储指针的数组和类型标记数组
#define ARR_SIZE 10
void* struct_arr[ARR_SIZE];
StructType type_arr[ARR_SIZE];

// 存入示例(注意结构体要在堆/全局区,避免栈内存失效)
struct a* ptr_a = malloc(sizeof(struct a));
ptr_a->a_id = 456;
strcpy(ptr_a->a_data, "allocated struct a");
struct_arr[0] = ptr_a;
type_arr[0] = TYPE_A;

struct b my_b = {2.718, 1690001000, "stack struct b"};
struct_arr[1] = &my_b;
type_arr[1] = TYPE_B;

// 取出示例
if (type_arr[0] == TYPE_A) {
    struct a* target = (struct a*)struct_arr[0];
    printf("Type A Data: %s\n", target->a_data);
    free(target); // 记得释放堆内存
}

注意:如果存储栈上的结构体地址,要确保结构体的生命周期长于数组的使用周期,否则会出现野指针问题。

方案3:固定大小的字节数组(不推荐,类型不安全)

找到三个结构体中尺寸最大的那个,创建对应大小的char数组,用memcpy把结构体数据拷贝进去,同样需要类型标签来识别。这种方式完全依赖手动内存操作,容易出错,仅作为备选。

代码示例:

// 计算最大结构体尺寸
#define MAX_STRUCT_SIZE (sizeof(struct a) > sizeof(struct b) ? \
                        (sizeof(struct a) > sizeof(struct c) ? sizeof(struct a) : sizeof(struct c)) : \
                        (sizeof(struct b) > sizeof(struct c) ? sizeof(struct b) : sizeof(struct c)))

typedef enum { TYPE_A, TYPE_B, TYPE_C } StructType;

struct a { ... };
struct b { ... };
struct c { ... };

// 数组元素:类型标签 + 字节数组
typedef struct {
    StructType type;
    char data[MAX_STRUCT_SIZE];
} RawStruct;

RawStruct arr[10];

// 存入示例
struct a my_a = {789, "raw array test"};
arr[0].type = TYPE_A;
memcpy(arr[0].data, &my_a, sizeof(struct a));

// 取出示例
if (arr[0].type == TYPE_A) {
    struct a* target = (struct a*)arr[0].data;
    printf("Type A ID: %d\n", target->a_id);
}

缺点:需要手动计算最大尺寸,内存对齐可能出问题,类型转换完全不安全,调试难度大。

内容的提问来源于stack exchange,提问作者golo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 01:35:21