表示テーマ
Pointer — ポインタ
TL;DR
&x は x のアドレス、*p は p が指すオブジェクトを表します。間接参照する前に、適切な型の生存中のオブジェクトを指している必要があります。対象はISO Cです。
Example
c
#include <stdio.h>
static void increment(int *value)
{
if (value != NULL) {
++*value;
}
}
int main(void)
{
int count = 3;
int *p = &count;
increment(p);
printf("count = %d\n", count); /* 4 */
return 0;
}Explanation
ポインタも値渡しです。アドレスをコピーして渡すことで、関数内から呼び出し元のオブジェクトを変更できます。この例の increment は NULL を何もしない入力として扱います。
| 宣言 | 変更できるもの |
|---|---|
const int *p | p の指す先。*p はこのポインタ経由では変更不可 |
int * const p = &x | *p。p の指す先は変更不可 |
const int * const p = &x | どちらもこの宣言経由では変更不可 |
void * は汎用のオブジェクトポインタです。ISO Cでは、そのまま間接参照したり加算したりせず、対象に合うオブジェクトポインタ型で扱います。
Pitfalls
NULLチェックだけでは寿命を確認できない
未初期化ポインタ、解放済み領域へのポインタ、関数終了後のローカル変数へのポインタを間接参照すると未定義動作です。非NULLだから有効、とは限りません。
ポインタの加減算は、同じ配列内または末尾の1つ先までに限定します。末尾の1つ先のポインタはループの終了判定に使えますが、間接参照できません。
Related
参考
C11委員会草案 N1570 §6.3.2.3、§6.5.3.2、§6.5.6、§6.7.3。