0

列挙型で指定された任意のタイプのデータを含むことができる完全に汎用的なリンクリストを作成する必要があります...

リストのノードの構造は次のとおりです。

  __________________
  |_____|_____|_____|

最初のフィールドは、格納されている情報のタイプを含むsizeof(nodeType)バイトです。次のフィールドには、情報変数のアドレスを含むアドレスがあります。次のフィールドには、次のノードのアドレスがあります。これは、単純なノードまたはさらに別のリンクリストにすることができます。

基本的に、私は次のようなnodeType列挙型を持っています:

 typedef enum{
    STRING, INT, NIL, LIST
 } nodType;

次のようにノードポインタにメモリを割り当てました。

 nodeType* node = malloc(sizeof(nodeType) + 2*sizeof(char*));

最初のsizeof(nodeType)バイトには、格納されている情報のタイプが含まれています。次の式で値STRINGを割り当てました。

 *node = STRING;

ここで、次のsizeof(char *)バイトにchar*ポインターのアドレスを格納する必要があります。(すべてのポインターはマシン上で同じサイズですか?(はい、私に一致します))。したがって、次のように値を割り当てます。

 char* str = strdup("Hello");
 (char**)(char*(node) + sizeof(nodeType)) = &str;

しかし、代入演算子のLHSは左辺値ではないため、GCCはエラーにフラグを立てます。リストの作成に進むには、そのアドレスに値を割り当てる必要があります。構造体を使用する以外に、cでそれを行うエレガントな方法はありますか?

4

1 に答える 1

4

逆参照するのを忘れました:

*(char***)((char*)node + sizeof(nodeType)) = &str;

間接参照操作の結果は常に左辺値です。p一般に、メモリ位置をタイプの変数を指しているかのように扱いたい場合はT、それをにキャストしてT *逆参照する必要があります。

*(T*)(p) = my_t_value;

T = char **これは、との状況に当てはまりますp = (char *) node + sizeof(nodeType)


しかし、これはひどいデザインです。正気の人はを含むべきではありません***。さらに、すべての要素がメモリ内で連続して続くと想定することにより、配置の制約に違反している可能性があります。もっと簡単な方法は次のようになります。

struct Node
{
    struct Node * next;

    nodType type;
    void * data;
};

使用法:

struct Node * p = malloc(sizeof *p);
p->next = NULL;
p->type = STRING;
p->data = str;

文字列を。へのポインタとしてではchar *なくとして直接格納することを選択したことに注意してくださいchar *。統一テーマは、リストノードが所有することであり、ノードの削除時に無条件にp->data言う必要があります。free(p->data);

于 2012-10-06T12:12:54.410 に答える