第6講 ポインタの学習

第5話 ポインタのポインタの簡単な演習

では具体的に見ていきましょう。
次のようなForm1をつくり、
q
次のようにコーティングしてみましょう。
#pragma endregion
    private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
            int** a;
            int* b;
            int c;
            c=5;
            b=&c;
            a=(int** )malloc;
            *a=b;
            label1->Text=(*b).ToString();
            label2->Text=(**a).ToString();
         }
};
}
実行結果は、
t
で同じです。
b=&c; と *a=b; によって、
k
cのアドレスがbと*aに入っています。
ですから、*a=b=&cです。
今回は入れていませんが、bのアドレスも&bもaに代入することもできます。
a=&b;
l
プログラミングは次のように変更しても同じです。
#pragma endregion
    private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
            int** a;
            int* b;
            int c;
            c=5;
            b=&c;
            a=(int** )malloc;
            
a=&b;
            label1->Text=(*b).ToString();
            label2->Text=(**a).ToString();
         }
};
}

これはどういうことでしょうか。
a
int** a;と宣言すると、aと*aと**aの3つを同時に操作できるようになります。
第2話で int *a; と宣言するとポインタ変数aと普通の変数*aを同時に宣言したことになると説明しましたが、
これは比喩的な表現で、もう少し正確に表現するとaから*aを参照できるようになるということです。
この表現を使うと、ポインタのポインタaから*aと**aと参照できます。
int** a; としたとき3つの変数を宣言しているのではなく、宣言しているのはあくまでaのみです。
しかし、*aと**aを見ることができるようになります。

u
aには変数bのアドレス&b
(0100000 こう書いているのはあくまで仮のアドレスです。
実際には、こんな単純な割り振りはしませんし、16進数表現です。
わかりやすさ優先でこう表現しています。)
が入っています。*aはそのアドレスのメモリーに収納されているデータを参照しなさい、という命令なのです。
さらに、bにはcのアドレス00000000が入っています。
**aは、そのアドレスのメモリーにはいっているデータ内容を参照しなさいということなのです。
結果的には、aから*aであるbと**aであるcを参照することができます。
*aとはaに収納されているアドレスのメモリ(箱)の中身を見なさいということなのです。
上の例では、aは01000000です。*aとは、01000000というアドレスのメモリの中身ということで00000000が参照されます。
同様にして、**aは*aに収納されているアドレスのメモリ(箱)の中身を見なさいということで5が参照されるのです。
図は次のように書き直した方がわかりやすいでしょうか。
z
結局aから*aと**aが参照できています。

頭が混乱してしまいますが、ポインタを理解するとC言語の仕組みが見えてきます。

魅力があると同時にC言語を難しくしている、と第1話でいった意味が少し見えてきたのではないでしょうか。

最後に課題を出してこの話を閉じましょう。
コード
#pragma endregion
    private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
            int** a;
            int* b;
            int c;
            c=5;
            b=&c;
            a=(int** )malloc;
            
a=&b;
            label1->Text=(*b).ToString();
            label2->Text=(**a).ToString();
         }
};
}

少し変更して、実行結果が
j
int c; は配列int c[5]; としてください。
label1もlabel2もfor文で実現してください。
今回と同様にlabel1には*bをlabel2には*aを利用してください。
尚、bに入れストアドレスを代入するときは、
b=&(c[0]); または b=c; です。





第4話へ 第6話へ


025


vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ



数学研究室に戻る