ポインタと参照

C,C++にはポインと参照という独特の概念があります。これらの概念が分かるか分からないかがこの言語を理解できるかどうかの大きな分かれ道となります。

それでは、以下のプログラムを見てください。

int main(int argc, char* argv[])
{
        int a = 1;
       
int& b = a;  //bはaと同じもの
       
int* c; //ポインタ
       
c = &a; //cにaの場所(アドレス)を入れる

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

    getc(stdin);//Enterキーが押されるまで待つ

    return 0;//処理の終わり
}

int& b = a;は、aの別名をbとするということです。bのことを変数aの参照と呼びます。bはaと同一のものとみなされますのでaが変化するとbも変化します。逆にbが変化するとaも変化します。

int main(int argc, char* argv[])
{
        int a = 1;
       
int& b = a;  //bはaと同じもの

       
b = 2; //aも変化する

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

    getc(stdin);//Enterキーが押されるまで待つ

    return 0;//処理の終わり
}

2番目のプログラムのようにb=2とするとaも2になります。

1番目のプログラムに戻ります。
c = &a; は、ポインタcにaのアドレス(場所)を入れるという意味です。int &b = a;のときの&の意味と異なりますので注意してください。

int a;のように既にaが普通の変数として宣言されている場合、その変数の前に&を付けるとその変数のアドレスを表します。アドレスはポインタにだけ入れることが出来ますので、
int a;
int b;
b = &a;
とは書けません。

以下の表は、1番目のプログラムを実行したときのメモリの中のイメージを表したものです。aとbは同じなので同じアドレスになることになります。b=2;としたのでその内容は2になっています。その下の行は、他の変数が次のアドレスにあることを意味していますが、これは実際にどうなっているかは状況によって変わります。そして、何個かのアドレスのあとcの場所が現れます。cはポインタなのでaのアドレス(=bのアドレス)が内容に入っています。この例ではアドレスを表す数が200210となっていますが、これはたまたまそうなっているだけで、実行するたびに異なるのが普通です。

変数名 アドレス 内容
a,b 200210 2
他の変数 200211 何か
 

・・・

 

c 210011 200210

表のcのところを見ると、内容はaのアドレスですからそのアドレスを使ってaの内容を見たり変更したり出来ます。

cを使ってaを操作するときは、*cとします。例えば、

*c = 1; とするとaの内容が変わります。

また、

int d = *c;とするとaの内容がdの中に入ります。つぎのプログラムで確かめてください。

int main(int argc, char* argv[])
{
        int a = 1;
       
int& b = a;  //bはaと同じもの
       
int* c; //ポインタ
       
c = &a; //cにaの場所(アドレス)を入れる

       
*c = 3; //aが3になる
        i
nt d = *c;// aの内容がdにはいる

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

    getc(stdin);//Enterキーが押されるまで待つ

    return 0;//処理の終わり
}

 

入力にはscanf

これはでキー入力(正しくは標準入力)にはgetcを使っていましたが、もう少し高性能なscanfを使ってみましょう。ポインタや参照の知識を使いますのでそれらの復習にもなります。

printfが表示すのと逆にscanfは入力します。"%d"などの使い方も似ています。以下のプログラムを見てください。

#pragma hdrstop
#include <condefs.h>
#include <stdio.h>



//---------------------------------------------------------------------------

#pragma argsused
//メイン関数
//実行は必ずここから始まる。

int main(int argc, char* argv[])
{
    char text[100];

    printf("何か文字を打って最後にEnterを押してください。(99文字以内)\n");

    scanf("%s", text);

    printf("あなたが打った文字は「%s」ですね?\n",text);

    getc(stdin);
//Enterキーを読み飛ばす。
    getc(stdin);//Enterキーが押されるまで待つ

    return 0;
}

scanf("%s", text);とすると入力されたものを文字列としてtextに格納します。

scanf("%d", &a); (aが整数型の変数として)このように記述すると入力されたものを整数としてaに格納します。

scanfの引数には変数のアドレスを渡します。変数の前に&を付けるとアドレスになるというのは覚えていますか?

また、int a[100];などとしたとき、aは配列のアドレスとなることも説明しました。

int main(int argc, char* argv[])
{
    int a;

    printf("何か数字を打って最後にEnterを押してください。\n");

    scanf("%d", &a);

    printf("あなたが打った数字は「%d」ですね?\n",a);

    getc(stdin);
//Enterキーを読み飛ばす。
    getc(stdin);//Enterキーが押されるまで待つ

    return 0;
}

double型を使うときは少し難しくて

double a;としておいて、

scanf("%le", &a);とします。

どうしそうなるか気になる人は、helpで調べてみてください。

 

ところで、scanfにアドレスを渡すということはポインタも使えるはずです。

int main(int argc, char* argv[])
{
    int a;
    int* b = &a;

    printf("何か数字を打って最後にEnterを押してください。\n");

    scanf("%d", b);

    printf("あなたが打った数字は「%d」ですね?\n",*b);

    getc(stdin);
//Enterキーを読み飛ばす。
    getc(stdin);//Enterキーが押されるまで待つ

    return 0;
}

次の課題はscanfを使いますのでマスターしてください。