C言語のポインタの使い方が驚くほどよくわかるサンプルコード

「ポインタは、メモリ上のデータを操作するためにある」

それがよくわかるサンプルコードを考えてみました。
#include <stdio.h>

int main()
{
    int c,b,a;

    a=1;
    b=2;
    c=3;

    printf("a=%d, b=%d, c=%d\n", a,b,c);

    printf("address of a is %p\n", &a);
    printf("address of b is %p\n", &b);
    printf("address of c is %p\n", &c);

    int *p;
    p = &b;
    
    printf("address of p-1 is %p\n", p-1);
    printf("address of p   is %p\n", p);  
    printf("address of p+1 is %p\n", p+1);
    

    *(p-1) = 0;
    *(p+1) = 4;

    printf("a=%d, b=%d, c=%d\n", a,b,c);
}

解説

    int c,b,a;

    a=1;
    b=2;
    c=3;

    printf(&quot;a=%d, b=%d, c=%d\n&quot;, a,b,c);
まず、a,b,c3つのint型変数を宣言して、値を代入します。
中身をprintfすると値が見れます。
実行結果
a=1, b=2, c=3
ここは問題ないですね。

つぎです。
    printf("address of a is %p\n", &a);
    printf("address of b is %p\n", &b);
    printf("address of c is %p\n", &c);
これは、宣言したa,b,cのメモリ上の番地を表示します。
実行結果
私のPCでは下記のような結果になりました。 (環境によって結果は異なります。)
address of a is 0022FF10
address of b is 0022FF14
address of c is 0022FF18
aとbのアドレス差、およびbとcのアドレス差が4になっています。(64bitマシンだとこれが8になるかも)
私のPCではINT型変数の大きさは4バイトなので、こういう結果になります。

例えて言えば、aさんbさんcさんの家がどれも1辺4メートルで、隣り合って並んでいると考えればよいでしょう。
計算機的に言うと、aとbとcがメモリ上に並んで敷き詰められているということです。
    int *p;
    p = &b;
さてここでポインタ登場です。
ポインタには、bさんの家の住所がセットされました。
    printf("address of p-1 is %p\n", p-1);
    printf("address of p   is %p\n", p);  
    printf("address of p+1 is %p\n", p+1);
さて、ポインタを前後に1づつずらしながら、それが指す住所を表示してみます。
pはint型のデータを指すポインタなので、「1ずらす」とは「4バイトずらす」ことと解釈されます。
実行結果
address of a is 0022FF10
address of b is 0022FF14
address of c is 0022FF18
さきほどと同じ結果になりました。
つまり、aさんbさんcさんの住所が表示されました。

さてここからが本番です。
bさんの「隣の家」に直接データを置いてみたらどうなるでしょうか?
    *(p-1) = 0;
    *(p+1) = 4;
ポインタはbさんの住所を指しているのですが、ここでbさんの「両隣の家」に値を代入してみます。
これはつまり、aさんとcさんの家にデータを置いたということなるはずです。
    printf("a=%d, b=%d, c=%d\n", a,b,c);
ではaさんbさんcさんの家にあるものを見せてもらいましょう。
a=0, b=2, c=4
おお!
aさんとcさんの中身が変わっていますね。

これで、ポインタの使い方がよくわかりました。
「ポインタは、メモリ上のデータを操作するためにある」
ということが実感できたかと思います。

Happy Pointing!
カテゴリ:

人気記事