C 文字列配列 新しいページはコチラ
提供: yonewiki
(ページの作成:「※このページではC言語にも存在していたという意味で記事タイトルがC 文字列配列になっていますが、<br /> C++でも...」) |
|||
1行: | 1行: | ||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る | ||
+ | |||
+ | |||
※このページではC言語にも存在していたという意味で記事タイトルがC 文字列配列になっていますが、<br /> | ※このページではC言語にも存在していたという意味で記事タイトルがC 文字列配列になっていますが、<br /> | ||
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | [[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | ||
<br /> | <br /> | ||
== '''文字列配列''' == | == '''文字列配列''' == | ||
+ | |||
文字列そのものが配列なのでした。<br /> | 文字列そのものが配列なのでした。<br /> | ||
char cStr0[]="yonewiki";<br /> | char cStr0[]="yonewiki";<br /> | ||
70行: | 74行: | ||
そうすると<br /> | そうすると<br /> | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
+ | char *cStr0[]={"yonewiki","mediawiki","google"}; | ||
for(int i=0;i < sizeof(cStr0)/sizeof(cStr0[0]);i++){ | 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 << "]=" << &cStr0[i] << "\n";//文字列リテラルの先頭アドレスを格納しているアドレス | std::cout << "cStr0[" << i << "]=" << &cStr0[i] << "\n";//文字列リテラルの先頭アドレスを格納しているアドレス | ||
− | std::cout << "cStr0[" << i << "]=" << (void*)*&cStr0[i] << "\n";文字列リテラルの先頭アドレス | + | std::cout << "cStr0[" << i << "]=" << (void*)*&cStr0[i] << "\n";//文字列リテラルの先頭アドレス |
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
87行: | 92行: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
とすることもできます。<br /> | とすることもできます。<br /> | ||
+ | ん~。このへんから、もう理解できないって人が増えてくる。<br /> | ||
+ | char型の文字列が既に配列で先頭アドレスってのを示すことでcout関数とかで出力ができてた。<br /> | ||
+ | その先頭アドレスを格納しているアドレス型の変数ってこと。ダメ?。<br /> | ||
+ | 絵が欲しい?わかった。<br /> | ||
+ | [[file:C_CharMatrixPoiterPointer.png]]<br /> | ||
+ | と上記のような絵を描いてみました。<br /> | ||
+ | 上側が*cStr[0]~[3]のアドレスが格納される配列です。0022FA18のアドレスから始まるその中に0133E410が格納されています。<br /> | ||
+ | 絵には少し嘘が入っていて、0133E410はリトルエンディアンという方式が採用されているせいで実際には逆順に10,E4,33,01と格納されてます。<br /> | ||
+ | リトルエンディアンの思想が紛らわしいのでとりあえず、順番に書いておきました。<br /> | ||
+ | それで、下側の方にあるアドレス0133E410の先頭からyonewikiと順番に格納されています。<br /> | ||
そうすると<br /> | そうすると<br /> | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
92行: | 107行: | ||
std::cout << "ppcStr[" << i << "]=" << ppcStr[i] << "\n"; | std::cout << "ppcStr[" << i << "]=" << ppcStr[i] << "\n"; | ||
} | } | ||
+ | </syntaxhighlight> | ||
+ | ってすると文字列が取得できます。 | ||
+ | 実行結果 | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | ppcStr[0]=yonewiki | ||
+ | ppcStr[1]=mediawiki | ||
+ | ppcStr[2]=google | ||
</syntaxhighlight> | </syntaxhighlight> | ||
なんだよppcStrって配列宣言してないのに、配列なのかよ。って思う人もいるかもしれません。<br /> | なんだよppcStrって配列宣言してないのに、配列なのかよ。って思う人もいるかもしれません。<br /> | ||
ポインタは配列のように指定することができて、この表記は<br /> | ポインタは配列のように指定することができて、この表記は<br /> | ||
− | ppcStr[i]から*(ppcStr+i) | + | ppcStr[i]から*(ppcStr+i)と書き換えることができます。<br /> |
− | + | <br /> | |
+ | (void*)ppcStr[i]というアドレスの中に書かれたアドレスを<br /> | ||
+ | ppcStr[i]や*(ppcStr+i)で指定しアドレスを指し示す。<br /> | ||
+ | <br /> | ||
+ | これがポインタであり配列なのです。他の型でもこれは同じことです。<br /> | ||
+ | ここではiが1増える都度、アドレスの大きさである4Byte分が大きくなって表示されます。<br /> | ||
+ | これのアドレスが移動している様(中身)を見たい場合は<br /> | ||
(void*)*(ppcStr+i)<br /> | (void*)*(ppcStr+i)<br /> | ||
とすると良いです。<br /> | とすると良いです。<br /> | ||
<br /> | <br /> | ||
+ | ここで、まだ理解ができていな人向けに説明しておくと<br /> | ||
+ | char **ppcStr;で定義したときはアドレスのアドレスのための変数でありながら、<br /> | ||
+ | 逆に、これを処理の中に記述すると<br /> | ||
+ | <nowiki>**ppcStr</nowiki>はppcStrに格納されているアドレスが指し示す中身の中身という意味になることです。<br /> | ||
+ | したがって、**(ppcStr)は'y'を示します。<br /> | ||
+ | printf("%c",**ppcStr);<br /> | ||
+ | 但し、厳密には以下のような記述が良いでしょう。<br /> | ||
+ | printf("%c",*(*(ppcStr + 0) + 1));で'o'と確認できます。<br /> | ||
+ | なぜならここで3つ定義した文字列リテラルはメモリアドレスの中で連続して配置されているとは限らないからです。<br /> | ||
+ | カッコを使って増やすアドレスを増加させる対象をわけておくのがいいでしょう。一番内側のカッコ内が<br /> | ||
+ | "yonewiki","mediawiki","google"の3つの要素を移動するためのアドレスを格納するのに必要な4Byteでの移動量を意味しています。<br /> | ||
+ | 外側がChar型変数の大きさ1Byteでの移動を意味しています。<br /> | ||
+ | ポインタのポインタを使った場合でも2つの指定しなければならない値があることで、2次元配列になっていることが実感できたと思います。<br /> | ||
+ | 興味本位で数字を増やして全部確認していくも良いですが、\0が表示されたらそこで処理を止めないと<br /> | ||
+ | 未定義の領域をポインタで参照することになり違反となります。<br /> | ||
+ | printf("%c",*(*(ppcStr + 1) + 0));なら"mediawiki"の先頭の'm'が表示されます。<br /> | ||
+ | <br /> | ||
+ | より理解を深めるためには、<br /> | ||
ポインタと配列を勉強しなおさないとダメですね。またそれは別の項目で記載します。<br /> | ポインタと配列を勉強しなおさないとダメですね。またそれは別の項目で記載します。<br /> | ||
<br /> | <br /> | ||
− | [[C PlusPlus|C++]]へ戻る | + | |
+ | |||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る |