3

次のような関数があるとします。

void foo(char **arr);

どうすれば次のことができますか。

void foo(char* x[] = { "hello", "my", "friend" });

これが混乱する場合、Java では次のようにしてこれを行います。

public void foo(String[] x);

foo(new String[] { "hello", "my", "friend" });

現在、私はCで次のことを行っていますが、それは本当に醜いので嫌いです:

char* myArr[] = 
    { 
        "hello", "my", "friend"
    };

foo(myArr);
4

3 に答える 3

5

どうすれば次のことができますか。

void foo(char* x[] = { "hello", "my", "friend" });

あなたはほとんどそれを作りました... ;-)

C99 以降を実行する場合は、次のような複合リテラルを使用します。

foo((char *[]){"hello", "my", "friend"});

呼び出された関数 (foo()ここ) には、ポインター配列に含まれる要素の数がわからないことに注意してください。そのため、最終的な null ポインターをセンチネルとして追加する必要があります。

foo((char *[]){"hello", "my", "friend", NULL});

例:

#include <stdio.h>
#include <stdlib.h> /* for EXIT_xxx macros */


void foo(char **arr)
{
  while (arr && *arr)
  {
    printf("%s\n", *arr);
    ++arr;
  }
}

int main(void)
{
  foo((char *[]){"hello", "my", "friend", NULL}); /* Mind the final NULL. */

  return EXIT_SUCCESS;
}

これは印刷されます:

hello
my
friend

複合リテラルは、定義されたスコープが残されるまで有効です (main()ここ)。使用直後にスタックから確実に削除されるようにしたい場合はfoo()、ローカル スコープ/ブロックを作成するための呼び出しを中かっこで囲みます。

int main(void)
{
  {
    foo((char *[]){"hello", "my", "friend", NULL}); /* Mind the final NULL. */
  }

  /* The compound literal passed to foo() is already deallocated here, had been 
     removed from the stack. */

  ...
于 2016-08-27T14:30:21.760 に答える
3

あなたは、に入ろうとする人々の別の犠牲者に違いありません。それが私が答える理由です。

そのパラメーター内で配列を初期化したい。どうすればそれができますか?

それはいけません。 C99より前


一般的に、これはあなたができることです:

#include <stdio.h>

void foo(char** arr, int size)
{
    int i;
    for(i = 0; i < size; ++i)
        printf("%s\n", arr[i]);
}

void bar(char** arr)
{
    while(*arr)
        printf("%s\n", *arr++);
}

int main(void)
{
    char* x[] = { "hello", "my", "friend" };
    foo(x, 3);

    char* null_terminated[] = { "ShadowRanger", "Correct", NULL };
    bar(null_terminated);

    return 0;
}

wherefoo()は配列のサイズを明示的に使用しますが、bar()配列は NULL で終了する必要があります。

于 2016-08-27T03:21:43.717 に答える