C言語のポインタを含む複雑な宣言を解読

スポンサーリンク

ちょっとC言語のソース読んでて、ポインタ( * )を含む複雑な宣言を読むのに苦労したので復習しました。復習のために目を通した本は、C言語ポインタ完全制覇と通称 K&R(プログラミング言語C)の2冊です。K&R はC言語の原典、C言語ポインタ完全制覇は昔ポインタを理解するために読んで、とても役に立った本。

【お知らせ】 英単語を画像イメージで楽に暗記できる辞書サイトを作りました。英語学習中の方は、ぜひご利用ください!
画像付き英語辞書 Imagict | 英単語をイメージで暗記
【開発記録】
英単語を画像イメージで暗記できる英語辞書サービスを作って公開しました
スポンサーリンク

C言語の複雑な宣言の解読方法

C言語ポインタ完全制覇のp144「Cの宣言を解読する」という章で、C言語の複雑な宣言を解読する方法が、ずばり分かりやすく説明してあります。以下、引用&要約。英語で解読すると分かりやすいので、英語で考えること推奨です。

1. 識別子に着目し、英語で読む
2. 優先順位:識別子に近い方から次の優先順位に従って派生型(配列、関数、ポインタ)を解釈する。
  1) 宣言をまとめる括弧
  2) 配列の []、関数の ()
  3) ポインタを意味する *
3. 派生型の解釈を、pointer to, array of, function returning のように to, of, returning で連結する
4. 最後に型指定子(左端のintやdoubleなど)を追加する
 

2 の優先順位を常に意識して読み進めるのがポイント。宣言をまとめるための括弧は優先度がもっとも高いので、そのまとまりを見つけたらまずそこを読む。そして次に、配列[]と関数()は、ポインタを意味する * より優先順位が高いことに注意する。

実際に複雑な宣言を読んでみる

C言語ポインタ完全制覇のP198「複雑な宣言を読んでみよう」の章で、難しい複雑なC言語の宣言の例が挙げてあります。それぞれいくつかピックアップして、復習のために実際に解読してみました。

1. まず識別子は atexit である
2. すぐ後ろの関数を表す () が最優先される => atexit is function returning
3. atexit の引数部分の () の中身を読む。(4〜6)
4. 識別子は func であり、(*func) と宣言をまとめる括弧がある => func is pointer to
5. (*func) の後ろの関数を表す () => func is pointer to function(void) returning
6. (*func) の型指定子は void => func is pointer to function(void) returning void
7. 最後に atexit の型指定子 int を追加 => atexit is function(…) returning int

上記の解読により、以下のような宣言であることが理解できました。

atexit is function(func is pointer to function(void) returning void) returning int.
atexitは、intを返す関数。引数は、voidを返す関数(引数なし)へのポインタ。

下が日本語に直したものですが、余計分かりにくくなるので、英語のまま理解したほうが良いと思う。

続いていくつか練習。

signal is pointer to function(int) returning void.
signalは、voidを返す関数(引数int)へのポインタ。

signal is function(sig is int, func is pointer to function(int) returning void) returning pointer to function(int) returning void.

ここまで複雑だと、日本語に翻訳すると余計難しいのでやめときます。

K&R(プログラミング言語C)の例を解読

K&RのP148、「複雑な宣言」の章でも、C言語の複雑な宣言についての説明があります。同様に例を解読してみる。

x is function returning pointer to array[] of pointer to function returning char

x is array[3] of pointer to function returning pointer to array[5] of char

いくつか練習すると慣れてきますね。K&R(プログラミング言語C)も何度も読み込んだはずなのですけど、内容をだいぶ忘れてしまっていました…orz。やっぱり日頃使っていない言語は忘れてしまいますね。

とりあえず、複雑な宣言も読み解けるようになりましたが、C言語ほとんど使わないので、だいぶ忘れちゃっていました。久しぶりにC言語のコードを読んだのですけど読みにくい、C言語は人間に優しくない…。やっぱり Ruby 最高です。

スポンサーリンク
 
スポンサーリンク

Leave Your Message!