-1

Cの文字列の長いリストに対してさまざまな機能を実行する必要があります。

char *list1[] = {"one","two","three", "four","five","six"};

最初は、単純なcar / cdr関数を実装しようとしていますが、しばらく経ち、Cでchar*[]のリストを管理する最良の方法を忘れています。cdrはchar*のリストの残りを返す必要があります。新たにmallocされた配列で。私の場合、それは「2」、「3」、「4」、「5」、「6」です。リストのサイズが不明なため、これが複雑になります。おそらく、リストの長さの構造体を使用する必要がありますか?

char **cdr(char *aList[]) {
  /*
   malloc space for n-1 char*
  */
  return aList; // Return everything to test
}

他の関数を使用します。たとえば、2つの連続する母音を持つすべての単語のリスト、または10文字より長い単語を返します。文字列を変更したくはありません(つまり、文字列は不変です)。cdrなどの関数でメモリをmallocするので、結果を取得して他の関数に渡すときに、それを追跡する必要があります。とにかく、誰かが私を始めてくれるなら、それは大いにありがたいです。ありがとう。

char *list1[] = {"one","two","three", "four","five","six"}; // Short list

char **cdr(char *aList[]) {
  /*
   malloc space for n-1 char*
  */
  return aList; // Return everything to test
}

char *car(char *aList[]) {
  return aList[0];
}

int main() {
  const char *first;
  char *rest[];

  int len = sizeof(list1)/sizeof(char*);
  printf("list1 len=%d\n", len);

  first = car(list1);
  rest = cdr(list1);

  printf("%s\n", first);
  len = sizeof(rest)/sizeof(char*);
  printf("rest len=%d\n", len);

  return 0;
}
4

3 に答える 3

2

リストのサイズが不明であるため、これは「不可能になる」ほど「複雑」ではありません。明示的な長さを渡したくない場合は、ターミネータとしてNULL値を使用する必要があります。

int length(const char* strings[]) {
    int rv = 0;
    while( strings[rv] ) ++rv;
    return rv;
}

int main(int argc, char *argv[]) {
    printf( "Note that this technique is also used in argv: %p\n", argv[argc] );

    const *list[] = { "+", "42", "30", NULL };
    printf( "Length: %d\n", length( list ) );

    return 0;
}

他の関数でこのようなlength()を使用すると、割り当てるメモリの適切な量を知ることができるはずです。(NULLの追加ポインター用にスペースを割り当てる必要があることに注意してください!)

于 2013-03-26T23:10:00.697 に答える
2

通常、探しているリストは配列としてではなく、リンクリストとして実装されます。それらが最初に実装された方法は、操作が「car」および「cdr」と呼ばれる理由です(http://en.wikipedia.org/wiki/CAR_and_CDRを参照)。

そのように実装されたリストは、2つのポインターを含む要素で構成されています。したがって、あなたの例では、そのようなリストは次のようになります。

 +-----+-----+    +-----+-----+    +-----+-----+         +-----+-----+   
 | car | cdr | -> | car | cdr | -> | car | cdr | -> .... | car | cdr | -> NIL
 +-----+-----+    +-----+-----+    +-----+-----+         +-----+-----+
   |                 |                |                     |
   v                 v                v                     v
 "one"             "two"            "three"               "six"

Cで同じことを実現するには、リストの要素に次のような構造体を使用することをお勧めします。

struct _Element {
  struct _Element *cdr;
  void  *car;
};

それでもアレイアプローチを使い続けたい場合は、代わりに「svk」の投稿をご覧ください。長さを個別に追跡する代わりにNULLで終了する配列を使用することは、提案したバージョンの興味深い代替手段になる可能性があります。

于 2013-03-26T23:10:05.123 に答える
0

Cでのマロッキングと解放はすべて、無駄であり、エラーが発生しやすいものです。実際の文字列を返すだけではどうでしょうか。

char * car (char ** list) {
    return list[0];
}

char ** cdr (char ** list) {
    return list + 1;
}
于 2013-03-27T13:27:34.550 に答える