No.1
- 回答日時:
へ?
「int main(int argc,char **argv[]) と書かれている場合」というのは, 例えばどこにあるのでしょうか?
int main(int argc,char **argv) ならわかるけど....
Tacosanさん、回答有り難う御座います。
>int main(int argc,char **argv) ならわかるけど....
int main(int argc,char **argv) でした、すみません、どのような意味でしょうか。
宜しくお願いします。
No.2
- 回答日時:
遅くまでお疲れ様。
>「**argv」と「*argv」の意味の違いはどのようなもので、どのように使い分けるのでしょうか。
違いは文法通りですよ。
main関数に渡される引数をポインタで受け取るか、ポインタのポインタで受け取るかの違いです。
下記のプログラムをデバッグして動きを見てください。(main関数に渡す引数は2個を想定してます。)
void main(int argc,char **argv[])
{
char buf[10]="";
printf("%d\n",argc);
printf("%s\n",argv[0]);//**argv[]の時になぜ正常に動作するかと言うと、printfがポインタのポインタでも動くように賢く作られてるからかな。。。動くがどうかは開発環境に依存するかも知れませんが、あんまり意識しないでください。
printf("%s\n",argv[1]);
printf("%s\n",argv[2]);
strcpy(buf,argv[0]);//コンパイルエラーになるが**argv[]→*argv[]に変えると正常に動作する
}
次になぜポインタのポインタで受け取るかと言う事ですが、Cを書く人のスタイルの差ですw
私は基本的にポインタのポインタは使わないように仕様を決めるので、使用経験が少ないので偉そうに説明するのは辞めときます。(でもコードは理解できますよ)
初心者と自分で言われているので、まずはC言語の最大の難関であるポインタを正しく理解してください。
ちなみにchar buf[10];と宣言したときのbufは特殊な動きをするポインタなので普通のポインタが理解できてから色々プログラムを組んで勉強してください。
ヒントは下記のプログラムです。(iに代入される値に注目)
char buf[10];
char *a=buf;
int i=0;
i=sizeof(buf);
i=sizeof(a);
ポインタのポインタはその次ですね。
bravheartさん、回答有り難う御座います。
早速下のコードで確認して
1
D:\eclipse\workspace\\Pointer\Debug\Pointer.exe
(null)
D
の結果になりましたが、printf("%d\n",argc)、printf("%s\n",argv[0])~("%s\n",argv[2])の内容が出力されているだけで、
この意味がさっぱり分かりません。
この内容に、**argv[]、*argv[]の違いのヒントが有るのでしょうか。
**argv[]、*argv[]の内容は変わらなかったのですが。。。
strcpy(buf,argv[0]);の後にprintf("%s\n",argv[0]);としても何も出力されなかったのですが、警告は出ていましたが???
==========================================================
void main(int argc,char **argv[])
{
char buf[10]="";
printf("%d\n",argc);
printf("%s\n",argv[0]);
printf("%s\n",argv[1]);
printf("%s\n",argv[2]);
strcpy(buf,argv[0]);
}
1
D:\eclipse\workspace\\Pointer\Debug\Pointer.exe
(null)
D
======================================
int main()
{
char buf[10] ;
char *a=buf ;
int i = 0 ;
i = sizeof(buf);
printf("%d\n",i);
i = sizeof(a);
printf("%d\n",i);
return 0;
}
10
4
=======================================================
>(iに代入される値に注目)
#これは、bufのアドレスのあるメモリサイズの大きさが、4と出てると考えていますが???
これが**argv[]とどのように繋がっていくのでしょうか。
No.3
- 回答日時:
変数宣言においては、ポインタと配列は全然別のものですが、
関数の引数では、配列はポインタとして扱われることになっています。そのため、
int main(int argc, char **argv)
int main(int argc, char *argv[])
この二つは、文法上は違いはありません。
意味はまったく同じですので、どちらで書いても同じ動作をします。
どちらで書くかは好みの問題です。
それぞれの言い分は
**argv派: 関数の引数に「配列」なんてものはないので、全部ポインタとして書く
*argv[]派: char*の配列=「文字列の配列」であるという設計の意図が分かりやすい
といったところでしょうか。
No.4
- 回答日時:
mtake2さんの言われている事に同意します。
>int main(int argc, char **argv)
>int main(int argc, char *argv[])
>この二つは、文法上は違いはありません。
ですが、本題は下記の違いですよね。
int main(int argc, char *argv[])
int main(int argc, char **argv[])
>この内容に、**argv[]、*argv[]の違いのヒントが有るのでしょうか。
ヒントはstrcpy(buf,argv[0]);です。
main関数の宣言を**argv[]と*argv[]で切り替えることでコンパイルエラーの内容や実際の動作に変化はないですか?
(コンパイル時にエラー内容、警告内容を理解するのは必須ですよ)
>#これは、bufのアドレスのあるメモリサイズの大きさが、4と出てると考えていますが???
i = sizeof(buf);
これが10と出力されている事に注目してください。
よく配列を宣言して、その配列を別関数に参照渡し(ポインタで渡す)する場合に下記のコードを書きますが、bufがポインタなら10と出力された事に疑問を持ちませんか?
void test(char *b);
int main(void)
{
char buf[10]="aaa";
test(buf);//この引数のbufはbuf[10]へのポインタではないのか?ポインタならsizeof(buf)の大きさは4byteではないのか?(これが説明できれば理解できています。)
printf("%s",buf);//参照渡し(ポインタでの引き回し)をしているので出力されている値はbbbとなっている。
return 0;
}
void test(char *b)
{
strcpy(b,"bbb");
}
質問者さんへ)
違いを理解するなら、まずは自分でプログラムを組んで、それを動かしてみて、実際に動作を確認して動きを理解することが大切です。
もしデバッグ環境がないのなら、コンソールに出力するなど工夫する事もまたプログラミングの勉強になります。
一度にたくさん理解しようとしないで、1個ずつ理解してください。
bravheartさん、回答有り難う御座います。
>bufがポインタなら10と出力された事に疑問を持ちませんか?
#bufがchar型の配列で要素数が10なら全体のサイズは「1byte*10要素」で10となるのは理解出来るのですが???
宜しくお願いします。
No.5
- 回答日時:
void test(char *b)
{
int i=sizeof(b);
strcpy(b,"bbb");
}
実際に動かさずにiに入る値が分かって、なんでそうなるのか説明できるなら理解出来てると思いますよ。
私は駆け出しの時、理解できてなくてバグを出して先輩に説教してもらった事があるんですけどね。。。
No.6
- 回答日時:
どうせなら
void test(char b[20])
{
int i=sizeof(b);
strcpy(b,"bbb");
}
の方がおもしろいかと>#5.
No.7
- 回答日時:
#6さん
お見それしましたw
恥ずかしながら一瞬で何を言われたいのが理解できませんでしたw
(ん? ただの参照渡し? しばらく思考停止。。。 なるほど!って感じでした)
個人的にはその手の話題は超好きなのですが、質問者さんにはちょっと早すぎる気がします。
チームで開発する場合、あえて使用する機会がどれだけあるかですけどね。。。
いい例があれば教えてください。
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
No.9
- 回答日時:
もちろん #6 は「きちんと理解できているかどうか」に使うものであって, 決して初心者向けではないです>#7. 実際問題として読みにくくする以外の効果もありませんし.
初心者向けには
1. 「ポインタ」と「配列」は別物である
2. ただし, 関数の引数に書いたときには「配列」は勝手に「ポインタ」とみなされる
3. 多くの場合「配列名」は「ポインタ」と同じように扱われる
というところでしょうか. 1 を押さえておくことは重要.
元の質問の例では関数 main の引数となっているので, 2つ目の char *argv[] は char **argv と全く同じです.
No.10
- 回答日時:
sizeofは演算子であって関数ではない。
←個人的にはこれが重要だからsizeof演算子に配列を渡した場合と、関数に配列を渡した場合の違いを見て欲しかったんです。
回りくどすぎたみたいですね。申し訳ないです。
元の質問がどっちか分からなくなりましたね。
最初の質問には
***************************************************************
main関数の引数で、int main(int argc,char **argv[])とint main(int argc,char *argv[])と書かれている場合がありますが、
「**argv」と「*argv」の意味の違いはどのようなもので、どのように使い分けるのでしょうか。
***************************************************************
と書いてますが、質問者さんの意図が分からないので辞めときます。
自称初心者さんは何が分かっていないかが分かっていないので。
bravheartさん、はじめ多くの方からの回答有り難うございます。
>自称初心者さんは何が分かっていないかが分かっていないので。
#確かに「何が分かっていないかが分かっていない」部分は有ります。
配列は元々アドレス渡しになっているので、「「**argv」と「*argv[]」は同じ意味としても考えられるということでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語のファイル入力が分かりません 2 2022/05/22 06:35
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
init関数の意味
-
fopne で失敗する原因
-
C言語のポインタに直接アドレス...
-
Run-Time Check Failure #3とい...
-
アプリを32bitから64bit移行
-
参照型で受け取った引数をポイ...
-
C言語の関数と配列に関する質問
-
C言語でのconstを返す関数
-
デバイスハンドルとは?
-
CObArrayとCPtrArrayの違い
-
プーさんのマウスポインタを教...
-
C# 配列とポインタの違い
-
ExcelVBAでのkernel32(64bit)
-
C言語 ポインタ
-
関数ポインタの利点
-
【C言語】戻り値が構造体の関数
-
構造体とfscanf
-
main(int argc,char **argv[])...
-
エラーの意味
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
C言語の関数と配列に関する質問
-
Run-Time Check Failure #3とい...
-
LPSTR型の初期化について
-
ExcelVBAでのkernel32(64bit)
-
main(int argc,char **argv[])...
-
アプリを32bitから64bit移行
-
ハンドルはポインタか
-
連結リスト 要素の入れ替え
-
C言語でのconstを返す関数
-
Cで作成したDLL関数をVBから呼...
-
NULLとブランクの違い
-
エラーの意味
-
ハンドル、アドレス、ポインタ...
-
DLL<->VB間での受け渡し(文字...
-
【C言語】戻り値が構造体の関数
おすすめ情報