1

是否可以将不同类型的结构嵌入到 C 中的另一个结构中?

基本上我想做这样的事情。

struct A { int n; void *config; }

struct AConfig { int a; char *b; }
struct BConfig { int a; float b; }

const struct A table[] = {
    { 103, (void*)(struct AConfig){ 1932, "hello" } },
    { 438, (void*)(struct BConfig){ 14829, 33.4f } }
}

这在 C 中是否可行,还是我必须单独定义结构?

4

4 回答 4

4

不,它不是那样工作的。您需要为每个结构显式存储:

struct A { int n; void *config; };

struct AConfig { int a; char *b; };
struct BConfig { int a; float b; };

struct AConfig ac = { 1932, "hello" };
struct BConfig bc = { 14829, 33.4f };

const struct A table[] = {
    { 103, &ac },
    { 438, &bc }
};

编辑:

另一种可能性是使用一个union和 C99 ( -std=c99) 命名的初始化器:

enum config_type { CT_INT, CT_FLOAT, CT_STRING };

union config_value {
    int int_value;
    float float_value;
    const char* string_value;
};

struct config {
    enum config_type ctype;
    union config_value cvalue;
};

struct config sys_config[] = {
    { CT_INT, { .int_value = 12 }}, 
    { CT_FLOAT, { .float_value = 3.14f }}, 
    { CT_STRING, { .string_value = "humppa" }}};

void print_config( const struct config* cfg ) {
    switch ( cfg->ctype ) {
        case CT_INT: 
            printf( "%d\n", cfg->cvalue.int_value ); break;      
        case CT_FLOAT:
            printf( "%f\n", cfg->cvalue.float_value ); break;
        case CT_STRING:
            printf( "%s\n", cfg->cvalue.string_value ); break;
        default:
            printf( "unknown config type\n" );
    }       
}
于 2010-07-17T20:40:02.703 回答
2

您可以使用联合:

struct AConfig { int a; char *b; };
struct BConfig { int a; float b; };
struct A {
    int n;
    union {
        struct AConfig a;
        struct BConfig b;
    };
};

请注意,ab在内存中的完全相同的空间中。所以如果你要使用A.a你不应该使用A.b,反之亦然。

由于这是一个匿名联合,您可以同时引用它们ab就好像它们是结构 A 的直接字段一样:

struct A sa;
sa.n = 3;
sa.b.a = 4;
sa.b.b = 3.14;
于 2010-07-17T21:22:07.923 回答
0

如果 BConfig 有一个指向 b 的浮点指针,它将起作用。

顺便说一句,也许您需要重构代码以适应 C 语法。

#include <stdio.h>
#include <stdlib.h>

typedef struct { int n; void *config; } Config;

typedef struct { int a; char *b; } AConfig;
typedef struct { int a; float *b; } BConfig;

int main(void) {
        AConfig A;
        BConfig B;
        A.a= 103;
        A.b= "hello";
        B.a= 438;
        B.b=(float *) malloc (sizeof(float));
        *(B.b)= 33.4f;
        const Config table[] = {
                { A.a, (void *) A.b },
                { B.a, (void *) B.b }
        };
        printf("Hi\n");
        return 0;
}
于 2010-07-17T20:00:57.387 回答
0

你可能更喜欢工会。我的联合语法有点生疏,但是是这样的:

union config { char* c; float d; };
struct A {int n; int a; union config b;};

const struct A table[] = {
    {103, 1932, { .c = "hello" } },
    {14829, 438, { .d = 33.4f } }
};

对于指定的初始化程序(表中的 .c 或 .d),您需要 C99,并且显然有一些方法可以判断您是在访问 char* 还是 float,但我假设您在其他地方已经涵盖了这一点。

于 2010-07-17T21:16:05.170 回答