#pragma twice

KAB-studio > プログラミング > #pragma twice > 068 Version 5.03 配列とポインタ

#pragma twice 068 Version 5.03 配列とポインタ

前のページへ 表紙・目次へ 次のページへ

 Version 5.03
配列とポインタ

前回は、リストボックスに文字列を追加しました。さて、ここに int i 
= 100 というのがあります。この i をリストボックスに追加したい、って
場合には?
んーと、 m_cDataLstBox.AddString( i ) じゃダメなんだよね……あ、エ
ラー

error C2664: 'AddString' : 
 1 番目の引数を 'int' から 'const char *' に変換できません。 
整数型からポインタ型への変換には reinterpret_cast、C スタイルキャスト
または関数スタイル キャストが必要です。

ん? ってことは、Ver 4.11 ( No.061 )で使ったキャストを使えばい
いんじゃない? m_cDataLstBox.AddString( (LPCTSTR)i ) みたいに
さてどうでしょう
う”っ……。あ、でもビルドしてもエラー出なかったよ? 実行して
も……あっ、強制終了!?
残念でした。まーこの辺は、文字列ってものがどういうものか分かんない
からしょうがないけどね
そうそう、しょーがないのよ。だからおせーて
はいはい。じゃ、まずテストアプリに切り替えて
テストアプリって、いつも使ってる、色々試す用の?
そうそう。何か調べたいときには、ちゃんとしたアプリのプログラムで試
すんじゃなくて、テストアプリで調べないと、間違えて書き換えちゃったり
するから
人体解剖を生きてる人でするよーなもんよね
ま、まぁ……
ん、テストアプリのワークスペース開いたよ。ボタンとハンドラも用意す
るね
うん。そしたらこういう関数を作って、ハンドラから呼び出して

void UseArray()
{
    int iAry[3];    // 配列。

    iAry[0] = 1;
    iAry[1] = 2;
    iAry[2] = 3;

    TRACE( "%X\n", iAry );
    TRACE( "%d, %d, %d\n", iAry[0], iAry[1], iAry[2] );
}   // ここにブレークポイント。

配列?
そう、配列は〈まとめて複数の変数を作る〉ための方法。最初の int 
iAry[3] で、 int 型の変数を3つ作ってます
3つって [3] で指定してるんだよね。なんかポインタのときに使った [ ] 
と似てて混乱しそう
そうそう、この辺は混乱するから注意して。で、これで iAry って変数が
作られます
3つできるんじゃないの?
 iAry から、3つを操作する仕組みになってるから。この iAry は、ほと
んどポインタ同然に操作できます
あ、そのあとの iAry[0] とかってポインタと同じ操作だもんね。えっと、
これだと *iAry と同じだよね
 iAry[1] は、憶えてる?
もちろん。 *( iAry + 1 ) と同じでしょ。 iAry の隣、 int は4バイト
サイズだから4バイト隣のアドレスの中身になるんだよね
そうそう。この辺は Ver 4.10 ( No.060 ) とかを参考にしてくださいっ
てことで、で、おなじみの
ブレークポイント! 最初の TRACE() は、 iAry のアドレスを表示する
んだよね。 & ついてないで表示できるんだから、やっぱ iAry ってポイン
タなんだ
その次の TRACE() は各要素の表示ってことで、結果は

64F528
1, 2, 3

で、このアドレスでメモリ見ればいいんだよね。えっと、こんな感じ

0064F528  01 00 00 00 02 00 00 00 03 00 00 00 8C F5 64 00 22 1D 40 00

これを4バイトごとに区切ると……

01 00 00 00 
02 00 00 00 
03 00 00 00 

あ、上から 1 2 3 だね。ってことは……
ってことは、配列っていうのは? 火美ちゃんの言葉で説明してみ
えーっと、たとえば int iAry[3] ってすると、メモリに int の変数分の
領域を、3つ並べて作ってくれるんだ! だから [0] とかのでそれぞれ書
き込めるんだね
そういうこと。ちなみに iAry[0] とかを〈要素〉って呼びます。 iAry[0]
を〈1番目の要素〉とか、〈これは要素数3の配列だ〉とか
ねー、 Ary って?
 Array を無理矢理縮めたの。 array はまんま〈配列〉って意味
……それって水希ちゃんローカル?
う”、そう……えーっと、配列はポインタと微妙に違うってことについて
どんなとこが? ほとんどポインタっぽいけど
それじゃ……あーっ!!
な、なに?
 sizeof って教えたっけ
教わってない
あらま。えーっと、じゃあまず次の関数

void Use_sizeof()
{
    char ch = 1;
    int i = 100;
    char *pi = &ch;
    TRACE
        ( "char : %d\nint : %d\nchar * : %d\n"
        , sizeof( ch ), sizeof( i ), sizeof( pi ) );
}

ん? 変数いっぱい作って、それに sizeof ってゆー関数を使って、その
戻り値を TRACE() で出力、だよね
 sizeof は関数じゃなくて、 C++ の機能のひとつ。ま、関数みたいなも
のだけどね。機能は、その変数のサイズを返すっていうもの
んで結果は

char : 1
int : 4
char * : 4

 char は1バイト、 int は4バイト、当たり前ねー。あれ、 char のポ
インタは……あそっか、指し示す型は1バイトだけど、ポインタは4バイト
だもんね
そうそう、その辺間違えないでね。んじゃ、今度は配列のサイズ

void sizeof_Array()
{
    int iAry[3];
    int *pi = iAry;

    TRACE
        ( "int [3] : %d\nint * : %d\n"
        , sizeof( iAry ), sizeof( pi ) );
}

これも sizeof で見るってゆーのね。……?

int [3] : 12
int * : 4

あれ? なんで iAry が12バイトも? あ、 int が4バイトだから3
個で12バイトね。でもそしたら pi も12バイトでないの?
ここが配列とポインタの違い。配列は一見ポインタだけど、型の上ではポ
インタとは違うから。その違いのひとつが、この sizeof 
でもこれって、配列のサイズがわかって便利よね
ぶっぶー。確かに配列ならいいんだけど、ポインタに渡しちゃったら
もうサイズわかんないんだ、それじゃ使えないか。ってことは、他にサイ
ズ知る方法が
ないんだよね、これが
ええーっ!! それってすごく不便じゃない?
不便だよ。この辺も、配列の難しさかな
むー
あともうひとつ、ポインタと違うところ。配列にはアドレスが入ってるん
だよね
そりゃそうよ、ポインタにはアドレスが入ってるもんだもん
そう。で、この〈配列の中のアドレス〉は変えられません
どゆこと?
こういうこと

void CanNotMoveAddressInArray()
{
    int iAry[3];
    ++iAry; // エラー。
    *iAry = 100;
}

あ、エラー
つまり iAry の中のアドレスは変更不可能。もし ++ とか使いたい場合に
は、ポインタに入れて、それを操作する、ってことになるかな
なんか const みたい
そうそう、これは const に近いね。あんまり使わないからまだ教えてな
かったけど、〈ポインタのアドレスに対する const 〉もあるんだよ

void constAddress()
{
    int i = 100;
    int *const pi = &i;
    ++pi;  // エラー。
}

うわ、 * のあとに const !?
これでアドレス値が const になるから
えっと、指し示す変数を変えられなくするのが const int * で、アドレ
スを変えなくするのが int *const 、なんか混乱するー
両方組み合わせて const int *const もできるよ
あ”、そうなんだ……混乱するなー
話を戻して、配列っていうものはだいたい解った?
変数をメモリ上に並べてまとめて作るので、ポインタとほとんど同じ、だ
よね
そういうこと。で、ここが重要なんだけど、ポインタで使ってた [] での
指定とか、 ++ でのアドレスの移動とかは、全部配列のため、だから
あ! そういえばそうよ、ポインタだけ使ってた時って、 ++ で隣のアド
レス見たって、そこは他の変数だから使っちゃダメってことだったもん
配列なら各変数が並んでるから、 ++ で〈隣の要素〉に移れたりするわけ。
あ、もちろんアドレスをポインタに渡してからの話だけど
でもならさ、配列を先に説明した方がよかったんじゃない?
それは違うよ。火美ちゃんが今日配列をあっさり解ったのは、ポインタの
知識があったから
確かに、 [] とかをポインタに使う方法とか、メモリのイメージとかでき
てたから、配列もすんなり理解できたかな
ポインタの時に言ったけど、ポインタの難しいところは、配列。だからそ
の前に、ポインタとメモリを徹底的に理解してもらったわけ
配列を理解するためにはポインタも理解しなきゃダメ、だから?
そういうこと。しかも、配列はポインタとちょっと違う。その辺の難しさ
を乗り越えるために、まずポインタから教えたわけ
でも、ポインタでできる操作は、配列のためにある、ってことなんだ
その辺、頭の切り替えがうまくできれば、大丈夫なんじゃない?

/*
    Preview Next Story!
*/
って、今回は文字列の話じゃなかったの?
文字列は配列の一種だから
そうやってどんどん分量多くなってくんでしょう
ギク
というわけで次回
< Version 5.04 文字ってなーに >
につづく!
配列できるようになっても、楽しくなんかならないよっ!!
文字が解るようになったら楽しくなるよ、たぶん、きっと……
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。