2011-07-03 15 views
7

私は今日C言語を学んでいます。私は管理された言語(Java、C#、Pythonなど)でしばらく前からコーディングしてきました。私はポインタの詳細を理解していると思っていましたが、次に期待どおりに動作する次のコードを書きましたが、互換性のないポインタ型の警告が生成されました。このCコードがなぜ機能するのかについての説明

void setText(char* output) { 
    //code to set output to whatever, no problems here. 
} 

int main(int argc, const char* argv[]) { 
    char output[10]; 

    setText(&output); 

    //[EDITED] ...other test code which printf's and further manipulates output. 

    return 0; 
} 

だから私はGoogleで検索し、警告を処分した

setText(output); 

にライン

setText(&output); 

を変えてしまいました。しかし、今私はなぜ最初のものが全く働いているのか分かりません。私は(char * xはchar x [];と本質的に同じなので)私が知る限りではアドレスのアドレスを送っていました。私は何を誤解していますか、なぜこれらの両方が機能しますか?

+0

なぜ 'setText'がその実装を見ずに動作していたのか、あなたのことを言うのは難しいです。すべての 'setText'が変数を設定しても、その後にプログラムが終了しても、プログラムがあなたが望むことをしているかどうかは本当に分かりますか? – jwodder

+2

'T *'は 'T [K]'と同じではありません。例えば、 http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr – delnan

+0

@delnan:リンクが壊れているようです – Cameron

答えて

17

outputタイプは、(第二の変形が動作する理由である)関数呼び出しのコンテキストでchar *に減衰する、char [10]あります。

&outputのタイプはchar (*)[10]であり、つまり配列へのポインタです。これは同じことではないため、コンパイラの警告です。しかし、の値が&output(アドレス)はoutputの値に相当します(一旦それがchar *に減衰した場合)ので、最終結果は「期待どおり」です。

これはpedantryのように聞こえるかもしれませんが、かなり大きな違いがあります。以下を試してください:

void foo(const char *p) 
{ 
    printf("%s\n", p); 
} 

int main(void) 
{ 
    char output[][6] = { "Hello", "world" }; 

    foo(output[0] + 1); 
    foo(&output[0] + 1); 
} 

推奨読書は、the C FAQ on arrays and pointers、特に質問6.3と6.12です。

+1

そして、彼らは両方とも同じ場所を指しているので、警告にもかかわらず "うまくいく"。 –

+1

いい例。実際にここで何が起こっているかを実際に説明するのに役立ちます。 – hbw

+0

はい、その例が役に立ちました。ありがとうございました。 – atheaos

関連する問題