C 文字列配列のソースを表示
新しいページはコチラ
移動:
案内
,
検索
※このページではC言語にも存在していたという意味で記事タイトルがC 文字列配列になっていますが、<br /> [[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> <br /> == '''文字列配列''' == 文字列そのものが配列なのでした。<br /> char cStr0[]="yonewiki";<br /> ってすると大きさ9で配列番号0~8までが生成されます。そしてcStr0や&cStr0[0]は文字列配列の先頭アドレスを保持しています。<br /> 文字列を配列として扱う場合は、自然と2次元の配列になります。<br /> char cStr[][10]={"yonewiki","mediawiki","google"};<br /> とすると要素数3は自動で生成され、文字数の最大は自分で指定してあげなければなりません。<br /> それぞれの先頭アドレスは、<br /> &cStr[0][0],&cStr[1][0],&cStr[2][0]に格納されています。<br /> cStr[0],cStr[1],cStr[2]もアドレスを指定するという意味では同じです。<br /> &cStr[0],&cStr[1],&cStr[2]としてもアドレスが返ってきますが、<br /> cout関数ではアドレスを出力し、printf関数ではアドレスをいれれば%s書式指定するので文字列が出力されます。<br /> <br /> おいおいおい。わけわかんねぇぜ。って思われた人はいるかもしれません。文字列で勉強してきたことを覚えているからなんだと思います。<br /> &cStr0[0]とcStr0って書くとcout関数はアドレスを受け取り、文字列を出力するのでした。&cStr0って書くとアドレスが返ってきました。<br /> cout関数は文字列の&cStr0[0]だと文字列を、文字列配列の&cStr[0]だとアドレス。なんか同じように見えるんすけど…違うのが返ってくるんすね。<br /> <br /> <syntaxhighlight lang="cpp"> #include <iostream> int main() { char cStr0[] = "yonewiki"; char cStr[][10]={"yonewiki","mediawiki","google"}; std::cout << "&cStr0[0] =" << &cStr0[0] << "\n"; std::cout << "&cStr[0] =" << &cStr[0] << "\n"; return 0; } </syntaxhighlight> 出力結果 <syntaxhighlight lang="cpp"> &cStr0[0] =yonewiki &cStr[0] =002EF984 </syntaxhighlight> ってな具合です。文字列の配列になっているのか、ただの文字列なのかで、同じような記述でも意味が異なります。これはややこしい。<br /> 文字列配列はcStr[0]や&cStr[0][0]で文字列の出力。'''&cStr[0]'''でアドレス。<br /> 文字列は cStr0 や'''&cStr0[0]'''で文字列の出力。&cStr0でアドレス。<br /> このような対応になっています。太字部分が同じような書き方ですが、もともとの変数によって意味が違うのです。<br /> 変数がどういう文字列変数として定義されたのか、よく理解しないとダメだということを意味しています。<br /> <br /> もっと踏み込みます。<br /> charのポインタ型の変数<br /> char *pcStr_0,*pcStr_1,*pcStr_2;<br /> に文字列配列の先頭アドレスを格納させようとすると<br /> <syntaxhighlight lang="cpp"> char cStr0[] = "yonewiki"; char cStr1[] = "mediawiki"; char cStr2[] = "google"; char cStr[][10]={"yonewiki","mediawiki","google"}; char *pcStr_0,*pcStr_1,*pcStr_2; pcStr_0=cStr[0]; pcStr_1=cStr[1]; pcStr_2=cStr[2]; </syntaxhighlight> と記述しないといけませんが、ポインタと文字列は密接な関係にあるのでした。<br /> 文字列として宣言したcStr0[]はcStr0や&cStr0[0]として表現できるポインタ変数でもあります。<br /> だとしたら、以下のように記述できても良いのではないか?という発想です。<br /> char *cStr0="yonewiki";<br /> 実はできます。これは、配列に似ていますが、"yonewiki"という文字列がメモリ上に置かれて、その先頭アドレスを指し示そうとするものです。<br /> "yonewiki"のようなダブルクォーテーションで囲まれた文字列を文字列リテラルと言います。文字列リテラルがどこに配置されるか、わからないので、残念ながら書き換えることは保障されていません。<br /> 書き換えれないことはおいておいて、<br /> 更に、 <br /> char *cStr0の配列として<br /> char *cStr0[]={"yonewiki","mediawiki","google"};<br /> とできます。これなら文字列の長さを数える必要もないです。<br /> この場合、cStr0[0],cStr0[1],cStr0[2]には、それぞれの文字列リテラルへの先頭アドレスが格納されます。アドレスの先には文字列型のものが入っていると言っています。<br /> 配列の中の要素数は配列の全体のcStr0の大きさと配列一つ分のcStr0[0]の大きさを割り算で求めることができます。32bitアドレスなら12byte/4byteで3個ってことです。<br /> sizeof(cStr0)/sizeof(cStr0[0])です。<br /> そうすると<br /> <syntaxhighlight lang="cpp"> for(int i=0;i < sizeof(cStr0)/sizeof(cStr0[0]);i++){ std::cout << "cStr0[" << i << "]=" << cStr0[i] << "\n"; std::cout << "cStr0[" << i << "]=" << &cStr0[i] << "\n";//文字列リテラルの先頭アドレスを格納しているアドレス std::cout << "cStr0[" << i << "]=" << (void*)*&cStr0[i] << "\n";文字列リテラルの先頭アドレス } </syntaxhighlight> とすることで配列の中身を書き出すことも出来ます。<br /> この文字列配列のポインタは、&cStr0[i]が示すようにcStr0[0]=0022FA18,cStr0[1]=0022FA1C,cStr0[2]=0022FA20というアドレス(アドレスは実行する都度変わります。)を持っているだけですから<br /> 0022FA18に"yonewiki"という文字列の先頭アドレスを保持しているわけです。この中身のアドレスを見るには(void*)*&cStr0[i]とすれば良いわけです。<br /> そうすると0022FA18の中には→例えば0133E410というアドレス番号が格納されており、0133E410の中身に"yonewiki"の先頭文字の'y'の文字コードが格納されています。<br /> 更にこれを<br /> <syntaxhighlight lang="cpp"> char **ppcStr;// char型のポインタのポインタ char *cStr0[]={"yonewiki","mediawiki","google"}; ppcStr=cStr0; </syntaxhighlight> とすることもできます。<br /> そうすると<br /> <syntaxhighlight lang="cpp"> for(int i=0;i < sizeof(cStr0)/sizeof(cStr0[0]);i++){ std::cout << "ppcStr[" << i << "]=" << ppcStr[i] << "\n"; } </syntaxhighlight> なんだよppcStrって配列宣言してないのに、配列なのかよ。って思う人もいるかもしれません。<br /> ポインタは配列のように指定することができて、この表記は<br /> ppcStr[i]から*(ppcStr+i)と書き換えることができます。これがポインタであり配列なのです。他の型でもこれは同じことです。<br /> ここではiが1増える都度、アドレスの大きさである4Byte分が大きくなって表示されます。これのアドレスが移動している様(中身)を見たい場合は<br /> (void*)*(ppcStr+i)<br /> とすると良いです。<br /> <br /> ポインタと配列を勉強しなおさないとダメですね。またそれは別の項目で記載します。<br /> <br /> [[C PlusPlus|C++]]へ戻る
C 文字列配列
に戻る。
個人用ツール
ログイン
名前空間
ページ
議論
変種
表示
閲覧
ソースを表示
履歴表示
操作
検索
案内
メインページ
コミュニティ・ポータル
最近の出来事
最近の更新
おまかせ表示
ヘルプ
ツールボックス
リンク元
関連ページの更新状況
特別ページ