| なぜ argv は char *argv[] のような形になっているのでしょう? | ||
| argv が実現しようとしているのは、文字列の配列ですね。そこで、まず文字列について確認しましょう。これは終端を表す値 '\0' で終わる char 型の配列ですから、メモリ上では次のようになっています(メモリの中のイメージをもう少し具体的にしておいた方が良いのですが、それは次回にします)。 | ||
![]() |
||
| 「文字列」という名前になっていますが、実際には数値の羅列です。char というのはもちろん character という意味ですが、これは文字を表す特別な型ではなく、格納されるのは数値です。数値で「文字コード」を格納することによって、論理的に文字を表現しているだけです。そして文字を表す数値の羅列として、文字列を表現するのです。ですから、より現実に近いイメージは次のようになります。 | ||
![]() |
||
| さて、もし文字列の最大長が決まっているなら、文字列の配列は次のように2次元配列で表すことができるでしょう。 | ||
![]() |
||
| argv も、ポインタなどややこしいことをしないでこうすれば済むような気がするかもしれません。しかし実際には文字列の長さに制限はありません。制限する必要もないですし、もし制限してしまったら、いつかそれ以上の長さの文字列が必要になったときに困ってしまいます。たとえどんなプログラムを作る場合にでも十分な長さというものがあったとしても、それはとても大きな値なので2次元配列の中には無駄な領域がたくさんできてしまって、あっという間にメモリが足りなくなってしまいます。もしかしたら、配列の中で一番長い文字列に合わせて長さを決めるという方法も考えられるかもしれませんが、これだと短い文字列の後ろに無駄になる領域ができてしまいます。 | ||
| それで、argv は次のような形になっています(文字列を指すポインタの配列ですね)。 | ||
![]() |
||
| これなら格納する文字列の長さを制限する必要はありませんし、長い文字列と短い文字列を一緒にしてもメモリ領域の無駄を最小限にできます。 | ||
| なお、本物の argv では最後に 0 が格納されています。つまり、 argv[argc] は 0 です。argv はポインタの配列ですから、0 というのは、NULL ポインタの値ですね。 | ||
| 普通は argv にアクセスするときは argc の値を調べて argv[argc-1] とか argv[2] などのようにしますが、最後が 0 なので、while ループか何かで最初から順に 0 に出会うまで巡回して文字列を取り出すこともできます。 | ||
| さて、ここまで読んで argv の構造が理解できたでしょうか?これがわかると、今度は自分で応用することができます。つまり、文字列に限らず長さ(サイズ)が違うデータの集まりを上手にまとめるためにポインタの配列が使えるということです。使い慣れるととても便利な構造ですし、そうやって自分で argv を真似ているうちに、argv が特別なものではないということがわかるでしょう。argv は基本的なデータ構造の1つなのです。 | ||
| argv のような構造をもっと詳しく理解するためには、それがメモリのなかでどうなっているのかを想像できなければいけません。特にポインタのところでつまずく人が多いようなので、次回はその辺りを詳しく解説することにしましょう。 | ||
("Hello, ANOTHER world!" は2001年11月から2002年11月にかけて作成されたコンテンツです。)