2016-08-27 36 views
3

のパラメータの内の構造体など、配列を新しい関数を定義します私はbecausを憎むCに次の操作を行い、現在は、関数呼び出し

public void foo(String[] x); 

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

:、あなたを混乱させるJavaで、私たちは以下のことで、これを行いますそれは本当に醜いE:

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

foo(myArr); 
+1

私は親切にあなたが第二、全く関係のない質問をするアドバイスですが、新しい質問でヒント:いくつかの研究を最初に行う... :) – gsamaras

+0

短い答え:CはJavaではありません。 Javaの場合と同じ方法でC言語で行うことはできません。これはその一つです。あなたはJavaのやり方でこれを行うことができないことに感謝するCプログラマーを見つけるでしょう。 – Peter

答えて

5

はどのようにして次の操作を行うことができます:

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

あなたはほとんどそれを作りました...C99以降の使用、このような複合リテラルをやっ;-)

の場合:

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

マインドと呼ばれる関数(ここではfoo())は、あなたがしたいので、ポインタ配列は、持っているどのように多くの要素手掛かりを持っていないことセンチネル、最終ヌル・ポインタを追加:

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; 
} 

これは、印刷されます:それはで定義されてしまったスコープは(ここではmain())残されるまで

hello 
my 
friend 

化合物リテラルが有効です。あなたはそれがその使用は、ローカルスコープ/ブロック作成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. */ 

    ... 
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; 
} 

bar()がNULL終端する配列を必要とするfoo()は、明示的に配列のサイズを使用しています。

+0

申し訳ありませんが、私の質問を読まなかったようです。 'foo(x、3)'と入力したところを見てください。私はそのパラメータの**内部**の配列を初期化したいです。それはどうやってできますか? – Hatefiend

+2

@Hatefiend私はしました。それはいけません。 – gsamaras

+0

長さを渡す代わりに、 'NULL'センチネルを' char * '配列の最後に追加することで' arr [i] 'が' NULL'になるまで 'foo'を続けることができます。明示的な長さは通常より優れていますが、場合によってはセンチネルが便利です。 – ShadowRanger

5

JavaとCは異なるイディオムで異なる言語です。

私がいれば、Cを「Javaのような」ものに強制するのをやめようとしない。各言語を独自のメリットで受け入れる。あなたの最初の例

、一つの "醜い"、あなたはCPP [Cプリプロセッサ] ないを行いマクロ --a概念を使用することができ、Javaで存在する:

#define FOO(_av...) \ 
    do { \ 
     char *myArr[] = { _av, NULL }; \ 
     foo(myArr); \ 
    } while (0) 

FOO("hello", "my", "friend"); 

しかし、このおそらく多くの人が「かわいすぎる」とみなされるでしょう。いくつかの並べ替えのテーブルを作成する方が良い。

Javaがnewを実行するときはいつでも、ヒープ割り当てを行っています[遅いです]。それは部分的にはのすべてであるからです。は多かれ少なかれ "ヒープ上"でなければなりません。

Cはmallocでこれを行うことができますが、良いCプログラマはグローバル変数、静的変数、関数スコープ変数を持つため、不要なヒープ割り当てを避けるようにします。

+1

"しかし、これはたぶん多くの人にとって"あまりにもかわいい "と考えられます。"、またはあまりにも...:P:P:Pとにかく、私の答え、 – gsamaras