Можно ли «встроить» структуру типа переменной в другую структуру? (ССЗ) - PullRequest
1 голос
/ 17 июля 2010

Возможно ли встроить структуру различного типа в другую структуру в C?

В основном я хочу сделать что-то подобное.Я должен определить структуры отдельно?

Ответы [ 4 ]

3 голосов
/ 18 июля 2010

Нет, так не работает. Вам необходимо явное хранилище для каждой структуры:

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 }
};

Edit:

Другая возможность заключается в использовании именованных инициализаторов 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" );
    }       
}
1 голос
/ 18 июля 2010

Вы можете использовать объединение:

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

Обратите внимание, что a и b находятся в одном и том же месте в памяти.Поэтому, если вы собираетесь использовать A.a, вам не следует использовать A.b и наоборот.

Поскольку это анонимный союз, вы можете ссылаться на a и b, как если бы они былипрямые поля структуры A:

struct A sa;
sa.n = 3;
sa.b.a = 4;
sa.b.b = 3.14;
0 голосов
/ 18 июля 2010

Вы можете предпочесть союз.Мой синтаксис объединения немного ржавый, но что-то вроде этого:

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 } }
};

Вам нужен C99 для обозначенного инициализатора (.c или .d в таблице) и, очевидно, какой-то способ сказать, если вы 'Вы получаете доступ к char * или float, но я полагаю, что вы это где-то скрыли.

0 голосов
/ 18 июля 2010

Это сработало бы, если бы 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...