&
変数名
&
変数名で、その変数のアドレスを取得できる。
#include <stdio.h> int main(void) { int a = 100; double b = 123.4; char c = 'c'; // %p はアドレスを16進数8桁で表示 // sizeof(変数名) でその変数のサイズを取得 // 変数名の直前に"&"を付けると,その変数のアドレスを取得 printf("a: value;%10d size;%lu address;%p\n", a, sizeof(a), &a); printf("b: value;%10lf size;%lu address;%p\n", b, sizeof(b), &b); printf("c: value;%10c size;%lu address;%p\n", c, sizeof(c), &c); return 0; }
sizeof
演算子を使うことで、変数や型のバイト単位のサイズを取得できる。
ポインタ変数
ポインタ変数、または単にポインタとは、アドレスを代入するための変数。
変数宣言時に 型 *変数名
または型* 変数名
と宣言することで、ポインタ変数となる。
ポインタ変数はとりあえず NULL
で初期化しておく、いわゆるNULLポインタ。
ポインタ変数の変数名に *
をつけることで、ポインタ変数のアドレスが指し示す値にアクセスできる。
#include <stdio.h> void show(int, int, int); int main(void) { int a = 100; int b = 200; // 整数型のポインタ変数pをNULLで初期化。 int *p = NULL; p = &a; // ポインタ変数に*をつけると、そのアドレスの値に対応する。 show(a, b, *p); // p = &a なので、*p、 つまり、aのアドレスの値を400に書き換える。 *p = 400; show(a, b, *p); p = &b; show(a, b, *p); *p = 800; show(a, b, *p); return 0; } void show(int a, int b, int p) { printf("==================\n"); printf("a: value;%10d size;%lu address;%p\n", a, sizeof(a), &a); printf("b: value;%10d size;%lu address;%p\n", b, sizeof(b), &b); printf("c: value;%10d size;%lu address;%p\n", p, sizeof(p), &p); printf("==================\n"); }
ポインタ変数にアドレスを代入せずアクセスすると、Segmentation fault (core dumped)
で異常終了する。
#include <stdio.h> int main(void) { int *p = NULL; *p = 1; return 0; }
ポインタと関数
c言語では、関数は一つしか値を返すことができない。
ポインタを引数にすることで、実質的に複数の値を返すような関数を作成できる。
変数の値の交換
ポインタ変数を引数に持つ関数にすることで、変数の値の交換ができる。
#include <stdio.h> void swap(int*, int*); int main(void) { int x = 1; int y = 2; printf("x: %d, y: %d\n", x, y); swap(&x, &y); printf("x: %d, y: %d\n", x, y); return 0; } void swap(int* x, int* y) { int temp = *x; *x = *y; *y = temp; }