Cでのポインタの読み方
Cのポインタの読み方は、ルールを知らないと摩訶不思議です。
ルールを覚えれば、
-
int (*p[5])[3];
-
char (*(*fp)(void))(int);
なんてのも解読する事ができます。
大事な前程
ポインタを読む際には、「英語で読む」必要があります。
「え~、英語~」 と思う方もいるかもしれませんが、逆に日本語で読む方が大変です。
基本ルール
ルール
-
後置演算子が優先。
- 関数の()
- 配列の[]
- 前置はあとで。
要は、「後ろに何かあったら、後ろが優先」です。
演算子の英語での読み方
- * pointer to ...
- () function returning ...
- [] array of ...
Lesson 1
まず、演算子が単独で出てくる場合です。
Lesson 1-1 pointer to ...
int *p;
これは、まずpを見ましょう。
int *p;
→ p is ...
次に、その前後を見ます。後ろは;ですので、前置の*を読みます。
int *p;
→ p is a pointer to ...
pは、何かを指すポインタです。何を指すのでしょうか。 次に、再びその前後を見ます。後ろは;ですので、前のintを読みます。
int *p;
→ p is a pointer to int.
pは、intを指すポインタでした。
Lesson 1-2 array of ...
同様に、[]の場合もやってみます。
int a[5];
の場合は、
int a[5];
→ a is ...
aの前後にはintと[5]がありますが、後置の方が強いので、[]を読みます。
int a[5];
→ a is a array of ...
aは何かのarrayです。何のarrayでしょうか。 後ろには;しか無いので、前のintを読みます。
int a[5];
→ a is a array of int.
aは、intのarrayでした。
Lesson 1-3 function returning ...
char func(void);
→ func is ...
前のcharよりも後ろの()の方が強いので、
char func(void);
→ func is a function returning ...
funcは、何かを返す関数です。何を返すのでしょうか。 後ろにはもう;しかありません。前のcharを読んで、
char func(void);
→ func is a function returning char.
funcは、charを返す関数でした。
Lesson 2 合わせ技
ここまでは簡単なのですが、これらが組み合わさせると、難しく感じられます。
Lesson 2-1
int *p[5];
を見てみます。
int *p[5];
→ p is ...
前に*、後ろに[]がありますが、「後ろ優先」ですので、[]を読みます。
int *p[5];
→ p is a array of ...
pは何かのarrayです。何のarrayでしょうか。後ろは;ですので、前を読みます。
int *p[5];
→ p is a array of pointer to ...
pはpointerのarrayです。何を指すpointerでしょうか。 後ろはもう無いので、前を読み、
int *p[5];
→ p is a array of pointer to int.
pは、intを指すポインタの配列でした。
Lesson 2-2
int (*p)[5];
これは、先程の
int *p[5];
とは違います。
まずpの前後を見ると、括弧でグループ化されており、pの直後には何もありません。よって、pの前の*を読みます。
int (*p)[5];
→ p is a pointer to ...
pは何かを指すpointerです。何を指すのでしょうか。 後ろ優先ですので、後ろの[]を読みます。
int (*p)[5];
→ p is a pointer to array of ...
pは、何かのarrayへのpointerです。
int (*p)[5];
→ p is a pointer to array of int.
pは、intのarrayへのポインタです。
Lesson 2-3
int *(*p)(void);
これも、順に読んでいきましょう。
int *(*p)(void);
→ p is a pointer to ...
int *(*p)(void);
→ p is a pointer to function returning ...
int *(*p)(void);
→ p is a pointer to function returning pointer to int.
pは関数ポインタで、どんな関数かと言うと、intへのポインタを返す関数です。
Lesson 2-4
int (*p[5])[3]
→ p is a array of ...
int (*p[5])[3]
→ p is a array of pointer to ...
int (*p[5])[3]
→ p is a array of pointer to array of ...
int (*p[5])[3]
→ p is a array of pointer to array of int.
pはpointerのarray(サイズ5)です。pointerはそれぞれ、intのarray(サイズ3)を指します。
Lesson 2-5
ここまで来ると、もう簡単ですね。 最初の例として挙げた、以下を読んでみましょう。
char (*(*fp)(void))(int);
→ fp is a pointer to ...
char (*(*fp)(void))(int);
→ fp is a pointer to function returning ...
char (*(*fp)(void))(int);
→ fp is a pointer to function returning pointer to ...
char (*(*fp)(void))(int);
→ fp is a pointer to function returning pointer to function returning ...
char (*(*fp)(void))(int);
→ fp is a pointer to function returning pointer to function returning char.
まず、charを返す関数へのポインタを渡す関数があります。 fpは、その関数へのポインタです。
/* charを返す関数 */ char f(int a) { return 0; } /* charを返す関数へのポインタを返す関数 */ char (*func(void))(int a) { return f; } char (*(*fp)(void))(int) = func;
練習問題
- char *(*c[10])(int *p);
- int (*(*p)(int *a))[5];
Last Modified: 2008-05-19 Monday