3

一般的なリンクリストを処理するプログラムがあります。あるケースでは、文字列を保持するために使用します。新しいノードをリストに追加する関数で、次のことを実行します(特に..):

void list_append(list *list, void *element)
{

  // create the new node... 
  listNode *node = (listNode *)malloc(sizeof(listNode));
  node->data = malloc(list->elementSize); // NOTE : elementSize is set to be sizeof(char *)
  node->next = NULL;
  memcpy(node->data, element, list->elementSize);   //**

  // rest of the insertion operation....

今、list_append関数を呼び出す関数で、次のことを実行します:

 int numNames = 5;
 const char *names[] = { "David", "Kevin", "Michael", "Craig", "Jimi" }; //*

 int i;
 list list;
 list_new(&list, sizeof(char *), free_string ,compareString);

 char *name;
 for(i = 0; i < numNames; i++) {
 name = strdup(names[i]);
 list_append(&list, &name);  //****
 }

さらに、2 つの文字列を比較する「比較メソッド」があります。

int compareString(void *str1,void *str2)
{

return strcmp(*(char **)str1 ,*(char **)str2);
}

もしそうなら、いくつか質問があります: 1) memcpy が動作している行で何がコピーされますか ( 行 //** - ポインターまたはコンテンツ ? コピーするデータがcalling function (line //*)? 2) ジェネリック リンク リストのノードは、次のように定義されます。では、比較メソッドを使用するときに(char * )str1 にキャストする必要があるのはなぜですか? 別の方法で文字列をコピーした場合、キャストは異なるでしょうか? よろしくお願いします(!!)、ガイ。

3)別のこと-memcpyによって実行されるコピーアクションを次のように変更すると:

memcpy(node->data, element, strlen((char *)element) + 1); //**

それも機能します-2つの異なる方法に違いはありますか? もしそうなら - 何が良いですか?

4

1 に答える 1

1

1)ポインターではなく、要素に含まれるデータをコピーしています。ポインターをコピーする場合は、&element を 2 番目のパラメーターとして渡す必要があります。

2) コンパイラは void が何を指しているのか分からないため、その型にキャストする必要があります。

3) リンクされたリスト関数が一般的であると想定されている場合は、最初の実装の方が優れています。そうしないと、関数は文字列に対してのみ機能します。

于 2013-10-12T20:01:16.793 に答える