0

異なる構造に対して単一の関数(addnode)を作成する方法はありますか?私はこのシナリオを持っています:

typedef struct linkedlist_a *ptr_a;
typedef struct linkedlist_a
{
    /* content */
    ptr_a next;
} listA;

typedef struct linkedlist_b *ptr_b;
typedef struct linkedlist_b
{
    /* content */
    ptr_b next;
} listB;

listA *listA_addnode( listA *head, listA *node )
{
    listA *temp = head;
    if( temp == NULL )
    {
        temp = node;
    }
    else if( temp -> next == NULL )
    {
        temp -> next = node;
    }
    else
    {
        while( temp -> next ) temp = temp -> next;
        temp -> next = node;        
    }

    return head;
}


listB *listB_addnode( listB *head, listB *node )
{
    listB *temp = head;
    if( temp == NULL )
    {
        temp = node;
    }
    else if( temp -> next == NULL )
    {
        temp -> next = node;
    }
    else
    {
        while( temp -> next ) temp = temp -> next;
        temp -> next = node;        
    }

    return head;
}

2つの構造がある場合は、2つの関数を記述しても問題ありませんが、2つを超える場合は、どうすればよいですか?

4

2 に答える 2

1

リンクされたリストを表すさまざまな を使用する代わりにstruct、可能な解決策は、データのメンバーを持つ単一のリンクされたリストstructを作成することです。これにより、わずかに異なる署名を持つvoid*単一の関数が可能になります。add_node()

例えば:

struct linked_node
{
    void* data;
    struct linked_node* next;
};

void add_node(struct linked_node** a_head, void* a_data)
{
    struct linked_node* new_node = malloc(sizeof(*new_node));
    new_node->data = a_data;
    new_node->next = 0;
    if (!*a_head)
    {
        *a_head = new_node;
    }
    else
    {
        /* ... */
    }
}

このアプローチ、つまりdataメンバーの正しい解釈には危険があります。ただし、このアプローチは注意して要件を満たすことができます。

使用例(エラーチェック省略):

struct data_x { int i; char c; };
struct data_y { char* s; };

struct linked_node* list_x = 0;
struct data_x* dx = malloc(sizeof(*dx));
dx->i = 4;
dx->c = 'a';

add_node(&list_x, dx);

if (list_x)
{
    struct data_x* x = list_x->data;
    printf("x.i=%d x.c=%c\n", x->i, x->c);
}

struct linked_node* list_y = 0;
struct data_y* dy = malloc(sizeof(*dy));
dy->s = "hello";

add_node(&list_y, dy);

if (list_y)
{
    struct data_y* y = list_y->data;
    printf("y.s=%s\n", y->s);
}

オンライン デモhttp://ideone.com/iZO8hを参照してください。

于 2012-10-11T08:16:17.243 に答える
0

これを行う唯一の方法は、リンク要素が同じと呼ばれると仮定したマクロを使用することです (nextそこに渡したいすべての型に存在します)。

GNU スタイル コード アヘッド:-std=gnu98またはそれ以上

#define addnode( head, node ) ({\
    typeof(head) _head = (head);\
    typeof(node) _node = (node);\
    if( _head == NULL )\
    {\
        _head = _node;\
    }\
    else\
    {\
        while( _head -> next ) _head = _head -> next;\
        _head -> next = _node;        \
    }\
    \
    _head;\
})

これはかなり悪いプログラミングスタイルですが

于 2012-10-11T08:22:50.703 に答える