アドレスは、16進数で表された数で表されます。
<STEP1>
アドレスをのぞいてみよう!
scanfをするとき、変数だと「&変数名」がアドレス、配列だと「配列名」がアドレスだと学習しましたね。
アドレスを調べるときは、16進数の数値を、「%p」を使ってみることができます。
#include <stdio.h>
int main(){
int a; //変数を宣言
int b[2]; //配列を宣言
printf("%p\n", &a); //変数のアドレスを調べる
printf("%p\n", b); //アドレスの変数を調べる
return 0;
}
アドレスは、変数や配列を宣言した瞬間に勝手に割り当てがされます。PCや環境によって、アドレスが違います。
<STEP2>
変数や配列に値を代入しても、アドレスは変わらないことを確認しましょう
#include <stdio.h>
int main(){
int a;
int b[2];
printf("%p\n", &a);
printf("%p\n", b);
a = 1;
b[0] = 3;
printf("%p\n", &a);
printf("%p\n", b);
return 0;
}
先ほどのコードに続いて、値を代入したのちにアドレスの確認作業をしてみました。
値を代入しても、アドレスが変化しないことに注意してください。
「C言語では、変数や配列の宣言時に、メモリが確保される」と学習してきましたが、メモリと一緒に、アドレスも確定します。
<STEP3>
アドレスを格納する特殊な変数「ポインタ変数」
int *ポインタ名; //int型の変数のアドレスを格納する変数の宣言です
char *ポインタ名; //char型の変数のアドレスを格納する変数の宣言です
double *ポインタ名; //double型の変数のアドレスを格納する変数の宣言です
#include <stdio.h>
int main(){
int a;
printf("%p\n", &a);
int *pa; //ポインタの変数宣言をする際には*が必要です。
pa = &a; //これで、aのアドレスが、ポインタに格納されました。
printf("%p\n", pa);
return 0;
}
<STEP4>
ポインタは、変数の住所のこと!
をきちんと理解してください。
変数の住所がわかったら、変数名を指定しないでも、変数の値を取り出せそうじゃないですか??
変数の値を取り出したいときは、ポインタ名に、*をつけて、「*ポインタ名」で取り出すことができます。
#include <stdio.h>
int main(){
int a = 2;
int *pa;
pa = &a; //変数aのアドレスを、paにコピー
printf("%d\n", a);
printf("%d\n", *pa); //*ポインタ名で、変数aの中身にアクセスできる!
return 0;
}
<STEP3,4補足>
ポインタは、初期化も可能です。
STEP3の例ですと、
「 int *pa = &a; 」
で、初期化ができます。
<step5>
STEP4でも扱いましたが、*paは、変数aの中身のことでした。
変数aの中身に、直接値を代入したら、変数aはどうなるでしょうか。
#include <stdio.h>
int main(){
int a = 2;
int *pa = &a;
printf("%d\n", a);
*pa = 56;
printf("%d\n", a);
return 0;
}
*paは、変数の中身に直接アクセスできるので、*paに値を代入するということは、つまり、変数aに値を代入するという意味でした。