• 締切済み

main(int argc,char **argv[])の意味を教えて下さい

 今晩は、Cの初心者です宜しくお願いします。  main関数の引数で、int main(int argc,char **argv[])とint main(int argc,char *argv[])と書かれている場合がありますが、 「**argv」と「*argv」の意味の違いはどのようなもので、どのように使い分けるのでしょうか。 また、必ずポインタ型でとるという決まりでしょうか。 宜しくお願いします。

みんなの回答

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.14

これは質問者さん向けというより、半分他の回答者さんに向けたコメントですが、 おそらく質問者さんの本当の意図は、ポインタと配列の違いではなく、 main関数の引数宣言の仕方に2パターンあるが、これはどう使い分けるのか、 というところにあるのではないでしょうか。 私はそう考えて回答3を書きました。 ところが、質問者さんが**argv を **argv[]と書き間違えちゃったために、 質問を深読みしちゃって C言語におけるポインタとは何か、というかなり難易度の高い議題で 回答がいっぱい集まっちゃったと。 で、ちょっとだけ質問者さんを弁護。 質問者さんは回答1のお礼欄に > int main(int argc,char **argv) でした、すみません、どのような意味でしょうか。 と書かれています。 わたしが回答3を書こうとした時点で、すでにこのコメントがあったため、 私は回答3で関数の引数宣言における **argv と *argv[] の違いについて回答しています。 質問者さんは、こういう訂正は、こういうのはお礼ではなく補足コメントにすべきだったと思いますが、 回答された方々も、回答される前に、既に付けられた回答と、そこへの 質問者者さんのコメントなどをちゃんと読んでから回答していれば、 ここまでムダな回答が続くことが無かったんではないかと思います。

htgo
質問者

お礼

皆さん、多くの回答有難う御座いました。 もっと勉強してこのサイトに来ます。

noname#96502
noname#96502
回答No.13

>演算子と関数の違いじゃないよ~>#10. 「特定の場合」を除いて配列名はポインタに変換されるんだけど, その「特定の場合」の 1つが「sizeof のオペランドになったとき」です. あと単項& のオペランドのときも. その説明だと、sizeofは関数だけど特定の場合に該当するって聞こえますよ。 ↓の説明がありますので。 >. ただし, 関数の引数に書いたときには「配列」は勝手に「ポインタ」とみなされる

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.12

「関数の引数宣言においては」char **argv と char *argv[] は同じものです. それ以外では違うものと思ってください. 演算子と関数の違いじゃないよ~>#10. 「特定の場合」を除いて配列名はポインタに変換されるんだけど, その「特定の場合」の 1つが「sizeof のオペランドになったとき」です. あと単項& のオペランドのときも.

noname#96502
noname#96502
回答No.11

>「**argv」と「*argv[]」 皆さんが言われているように同じです。 もし最初から質問内容がこれなら、質問文を見直して欲しいです。 私だけかも知れませんが勘違いしました。 原文抜粋 >「**argv」と「*argv」の意味の違いはどのようなもので、どのように使い分けるのでしょうか。 補足 「「**argv[]」と「*argv[]」」や「「**argv」と「*argv」」 これは別物です。

noname#96502
noname#96502
回答No.10

sizeofは演算子であって関数ではない。←個人的にはこれが重要 だからsizeof演算子に配列を渡した場合と、関数に配列を渡した場合の違いを見て欲しかったんです。 回りくどすぎたみたいですね。申し訳ないです。 元の質問がどっちか分からなくなりましたね。 最初の質問には ***************************************************************  main関数の引数で、int main(int argc,char **argv[])とint main(int argc,char *argv[])と書かれている場合がありますが、 「**argv」と「*argv」の意味の違いはどのようなもので、どのように使い分けるのでしょうか。 *************************************************************** と書いてますが、質問者さんの意図が分からないので辞めときます。 自称初心者さんは何が分かっていないかが分かっていないので。

htgo
質問者

お礼

bravheartさん、はじめ多くの方からの回答有り難うございます。 >自称初心者さんは何が分かっていないかが分かっていないので。 #確かに「何が分かっていないかが分かっていない」部分は有ります。 配列は元々アドレス渡しになっているので、「「**argv」と「*argv[]」は同じ意味としても考えられるということでしょうか。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.9

もちろん #6 は「きちんと理解できているかどうか」に使うものであって, 決して初心者向けではないです>#7. 実際問題として読みにくくする以外の効果もありませんし. 初心者向けには 1. 「ポインタ」と「配列」は別物である 2. ただし, 関数の引数に書いたときには「配列」は勝手に「ポインタ」とみなされる 3. 多くの場合「配列名」は「ポインタ」と同じように扱われる というところでしょうか. 1 を押さえておくことは重要. 元の質問の例では関数 main の引数となっているので, 2つ目の char *argv[] は char **argv と全く同じです.

  • ricardo_
  • ベストアンサー率19% (14/72)
回答No.8

 次のプログラムがあなたの疑問に役立つかも知れません。 int main(void) { const static char *const List[] = /* ポインタの配列 */ {"Apple\r\n" , "Banana\r\n" , "Chery\r\n" } ; char **pointer ; /* ポインタのポインタ */ /************************* * プログラムの始まり * *************************/ /*=== Put_str() の機能を説明 ===*/ Put_str("Put_str() は、文字列を印刷する関数です。\r\n") ; /*=== 配列を使う方法 ===*/ Put_str(List[0]) ; Put_str(List[1]) ; Put_str(List[2]) ; /*=== ポインタを使う方法 ===*/ pointer = List ; Put_str(*pointer++) ; Put_str(*pointer++) ; Put_str(*pointer++) ; } *** 結果 *** Put_str() は、文字列を印刷する関数です。 Apple Banana Chery Apple Banana Chery

noname#96502
noname#96502
回答No.7

#6さん お見それしましたw 恥ずかしながら一瞬で何を言われたいのが理解できませんでしたw (ん? ただの参照渡し? しばらく思考停止。。。 なるほど!って感じでした) 個人的にはその手の話題は超好きなのですが、質問者さんにはちょっと早すぎる気がします。 チームで開発する場合、あえて使用する機会がどれだけあるかですけどね。。。 いい例があれば教えてください。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

どうせなら void test(char b[20]) { int i=sizeof(b); strcpy(b,"bbb"); } の方がおもしろいかと>#5.

noname#96502
noname#96502
回答No.5

void test(char *b) { int i=sizeof(b); strcpy(b,"bbb"); } 実際に動かさずにiに入る値が分かって、なんでそうなるのか説明できるなら理解出来てると思いますよ。 私は駆け出しの時、理解できてなくてバグを出して先輩に説教してもらった事があるんですけどね。。。