C:struct少一个字段。如何有效地声明/使用它?

时间:2013-02-17 06:18:05

标签: c struct variable-declaration type-declaration

假设我们有两个不同的struct,它们主要是常见的字段,但有一个或两个不同的字段或更少的字段。例如:

typedef struct HobbyNodetag {
    char *name; // hobby name
    struct HobbyNodetag* link; // link to next HobbyNode
    int count; // number of times this hobby was mentioned by user
    // more fields... 
    // but identical type/variable name with MyHobbyList
} HobbyNode; // database of entire hobby node; singly linked list

typedef struct MyHobbyTag{
    char *name; // hobby name
    struct MyHobbyTag* link; // linked to next MyHobbyNode
    // more fields... 
    // but identical type/variable name with EntireHobbyList
} MyHobbyNode; // single person's hobby node; singly linked list

我们是否有更高效/优雅的编码习惯才能使用上述两个struct s?这是不是浪费了两个不同的struct,因为他们分享了大部分领域?

更新

我之前的问题是误导性的。以上示例是节点并单链接(通过link)。

3 个答案:

答案 0 :(得分:6)

您可以将所有额外字段(存在于第二个结构中但不存在于第一个结构中)移动到结构类型定义的末尾,然后使用较小的结构作为较大结构的“基础”: / p>

struct BaseFoo {
    int count;
    char name[128];
    float value;
};

struct ExtendedFoo {
    struct BaseFoo base;
    struct ExtendedFoo *next;
};

这个解决方案的优点是你可以拥有“多态”:因为C标准保证在内存中第一个struct成员之前没有填充,这样就可以了:

void print_name(struct BaseFoo *foo)
{
    printf("Count: %d\n", foo->count);
    printf("Name: %s\n", foo->name);
}

struct ExtendedFoo foo = { /* initialize it */ };
print_name((BaseFoo *)&foo);

答案 1 :(得分:1)

你可以做这样的事情,但我相信这不是你想要的。

typedef struct myHobbyTag{
    char *name;
    struct myHobbyTag* link; 

} MyHobbyList; 

typedef struct entireHobbytag {
    MyHobbyList commonPart;

    int count;
} EntireHobbyList; 

答案 2 :(得分:0)

如果将所有公共字段移到顶部,则可以在C中使用OOP声明基类和继承类(在StackOverflow上搜索它。)

基本上有两种方法可以做到这一点。

  1. 您声明了一个基类,然后在继承类(包含更多字段)中将基类作为成员放在继承类的顶部。

    struct hobbyLink; //常用链接

    typedef struct baseHobbytag {
        char *name;
        struct hobbyLink* link;
    } BaseHobby; 
    
    typedef struct myHobbyTag{
        BaseHobby  hobby;
        int count;
        // more fields...
    } HobbyTag;
    
  2. 对所有公共基本成员使用#define,并将#define放在所有继承类中。

    #define BASEHOBBY_MEMBERS   \
    char *name;             \
    struct hobbyLink* link;
    
    // base class
    typedef struct baseHobbytag {
        BASEHOBBY_MEMBERS   
    } BaseHobby;
    
    // Inherit basehobby    
    typedef struct myHobbyTag{
        BASEHOBBY_MEMBERS   
        int count;
        // more fields...
    } HobbyTag;