rokiの戯言

コミュ障のコンピュータオタクがなんかほざきます。

配列、文字列、ポインタは同じものってことでいいのね?

C++見習いのrokiです。

のらりくらりとプログラミングの勉強をしている今日このごろ、ごくごく当然の事に気がついたので備忘のために書いておきます。

色々間違ったことをホザイているかもしれないので検索で辿り着いてしまった方はそのつもりで読んで頂きたいしだいです。

 

で、何に気がついたかというと。

配列も文字列も、要するにポインタってことでしょ。って話。

ポインタを理解するあたりまで勉強が進むと、ポインタ絡みの色々な事が頭のなかでごちゃまぜになって逆に解らなくなってしまった、という人もいるかと思います。

自分が正にそのパターンであるわけですが;;;

 

さて本題です。文字列の配列を作るときは

char* foo[2] = {"foo","bar"};

と宣言、初期化するわけですが。ポインタと配列と文字列の合わせ技になっていて結構複雑です。この時、配列変数はメモリ上に連続して確保した変数群の先頭のメモリアドレスを指す事と、文字列は文字の配列として表されているという点に注目します。

 

まず文字列、C/C++に置いて文字列とは文字型変数の配列として扱われます。

char* a="hello";

char b[6]={'h','e','l','l','o',0}; //0はターミネータ

と同じであるということです。

 

次に配列変数について、配列変数とは変数の型に必要な分のメモリ領域が指定された要素の数だけ連続的に確保されたものです。

上の例ではchar型の変数が6個確保されるので

f:id:roki0gjm:20130603141329p:plain

という具合に、メモリ上に48bitの領域が連続して確保されるわけです。

配列変数の名前(上の例では b )はコードの中で最初の要素のアドレスを指すポインタの役割を果たします。

char b[6]={'h','e','l','l','o',0};

cout<< b <<endl;

とすると、メモリアドレスが表示されると思います。

このアドレスは配列の先頭の要素のメモリのアドレスです。

配列変数はポインタである。これが重要です。

  • 文字列はchar型の配列変数
  • 配列変数はポインタ

この二点を押さえると最初の疑問の答えが出ます。

char* foo[2] = {"foo","bar"};

これは、配列変数fooの中に文字列型の配列変数が2つ格納されてるのです。

つまり上の宣言は

char foo[2][4] = {

                            {'f','o','o',0} , {'b','a','r',0}  //0はターミネータ

                           };

と書き換えられます。

そして"foo"というのは

配列 {'f','o','o',0} の先頭の要素を表すポインタの役割になります。

つまり、char型 8bit のメモリ領域を指すポインタです。

このポインタがさらに配列に格納されるので、一番上の配列の型はchar* になるわけです。

 

まとめると、配列も文字列もポインタなので、文字列を格納する配列変数の型はchar* になる。と言うことです。

 

きっとどこかに誤りのある記事なので、見つけたらコメントで指摘していただけると嬉しいです。

 

ではではノシ〜