- 更新日: 2015年4月21日
- Swift & iOS
C言語のポインタを含む複雑な宣言を解読
ちょっとC言語のソース読んでて、ポインタ( * )を含む複雑な宣言を読むのに苦労したので復習しました。復習のために目を通した本は、C言語ポインタ完全制覇と通称 K&R(プログラミング言語C)の2冊です。K&R はC言語の原典、C言語ポインタ完全制覇は昔ポインタを理解するために読んで、とても役に立った本。
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 2 3 |
int atexit(void (*func)(void)); |
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を返す関数(引数なし)へのポインタ。
下が日本語に直したものですが、余計分かりにくくなるので、英語のまま理解したほうが良いと思う。
続いていくつか練習。
1 2 3 |
void (*signal)(int); |
signal is pointer to function(int) returning void.
signalは、voidを返す関数(引数int)へのポインタ。
1 2 3 |
void (*signal(int sig, void (*func)(int)))(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言語の複雑な宣言についての説明があります。同様に例を解読してみる。
1 2 3 |
char (*(*x())[])(); |
x is function returning pointer to array[] of pointer to function returning char
1 2 3 |
char (*(*x[3])())[5]; |
x is array[3] of pointer to function returning pointer to array[5] of char
いくつか練習すると慣れてきますね。K&R(プログラミング言語C)も何度も読み込んだはずなのですけど、内容をだいぶ忘れてしまっていました…orz。やっぱり日頃使っていない言語は忘れてしまいますね。
とりあえず、複雑な宣言も読み解けるようになりましたが、C言語ほとんど使わないので、だいぶ忘れちゃっていました。久しぶりにC言語のコードを読んだのですけど読みにくい、C言語は人間に優しくない…。やっぱり Ruby 最高です。
- Swift & iOS の関連記事
- WKWebView/UIWebViewでウェブページが真っ白
- Unityのインストールと初期設定
- WKWebView/UIWebViewでNavigation Barの下にウェブページが隠れるのを回避
- SwiftでArray(配列)などをシャッフル
- Navigation Controllerで画面遷移させるSwiftコード
- Swiftでタップ/スワイプのイベント処理実装・UITapGestureRecognizerとUISwipeGestureRecognizer
- UIPageViewController画面下部のUIPageControlを非表示にする
- Swiftのバージョン確認・REPL実行
- Xcode7.0アップデートで遭遇した課題2つ
- 正規のXcodeかどうかチェック(XcodeGhostマルウェア騒動)
- 初回公開日: 2015年4月20日
Leave Your Message!