3

私はCの初心者で、ノードが次のように定義されているリンクリストを実装しようとしています:

typedef struct _cListNode
{
    void *_data;                //generic pointer to any data type
    struct _cListNode *next;    //next node in the list
} cListNode;

InsertElement(cList myList, void *dataToInsert) 関数を使用して、挿入される要素が既に存在する場合 (つまり、重複がない場合) にリストを拡大しないようにする必要があります。私の現在の問題は、 dataToInsert (パラメーター) を _ data (ノード内) と比較する方法が見つからないことです。

InsertElement 関数を呼び出す前にリストを外部からトラバースし、型が何であるかを知っているリストの実装の外部で比較を処理することを考えましたが、より良い設計/解決策を望んでいました。

4

2 に答える 2

4

2 つの void ポインタがある場合、それらのデータを比較することはできません。これは、各ポインターの型のサイズがわからないためです。それらのデータを比較したい場合は、ポインタとデータのサイズを保存する必要があります。次に、 memcmp を使用して、指定されたメモリを比較できます。

 typedef struct _cListNode
 {
     void *_data;                //generic pointer to any data type
     size_t size;
     struct _cListNode *next;    //next node in the list
 } cListNode;

 int memcmp ( const void * ptr1, const void * ptr2, size_t num );

そう:

 memcmp(node_data_ptr, new_data_ptr, size_of_item_pointed_at);

両方のポインターのサイズが同じである場合にのみ memcmp を実行する必要があります。それ以外の場合、それらは明らかに異なり、無効なメモリを比較することは望ましくありません。

他のオプションは、ポインター自体を比較して、それらがメモリの同じセクションを指しているかどうかを確認することです。「重複」の意味によって異なります。

于 2013-01-18T15:51:28.273 に答える
2

このようなことをしたいかもしれません。リンクされたリストの構造は次のようになっていると思います。

typedef struct _cList
{
   cListNode* head;
   cListNode* tail;
   size_t size;
} cList;

int contains(cList* list, void* data, size_t dataSize)
{
   cListNode* temp = list->head;

   while(temp)
   {
      if(!memcmp(data, temp->_data, dataSize))
         return 1;
      temp = temp->next;
   }
   return 0;
}


void InsertElement(cList* myList, void *dataToInsert, size_t dataSize)
{
   if(!contains(myList,dataToInsert, dataSize))
   {
     //Insert Data
   }
   else
   {
     //Data Is already present.
   }
}

struct cListNode@jmhの回答で指定されているように作成する必要があります。

于 2013-01-18T16:10:34.237 に答える