C言語ポインタ完全制覇を読んだ

久々の読書記録.

今回は「本を読みながら,LaTeXで自分なりにまとめておく」というライフハックを初めて実践しました.

ポインタからメモリ管理まわりに関して,凄く詳しく徹底的に書かれていて,逆にこっちが引くぐらい.Cの入門書を1冊終えて,2冊目あたりにおすすめです.

ただし,何回も同じことを繰り返すところがあり,そこは一長一短だと思います.(大事なことなので二回言いました的な)

ここにも,まとめておきます.

  • p[i]は*(p+i)のシンタックスシュガー(人間の可読性のために実装されたもので意味は同じ)→p[i]とi[p]は同じ,でも意味不明なので書くな!
  • 式の中では「型Tの配列」は「型Tへのポインタ」に常に置き換えられ,「関数」は「関数へのポインタ」に自動的に変換される
  • 復習ですが,
    • 間接参照演算子*はポインタをオペランドとして受けとり,その指し示すオブジェクトまたは関数を返す.*が返す式の型は,受け取ったオペランドの型からポインタを 1 つ剥がした型.
    • アドレス演算子&はオブジェクトをオペランドとして受けとり,それを指すポインタを返す.その型はオペランドの型にポインタを 1 つ付け加えた型になる.
    • 添字演算子 [] はポインタと整数をオペランドとして受け取る.p[i] は*(p + i) のシンタックスシュガーで,返す型は p の型からポインタを 1 つ剥がした型.
    • 関数呼び出し演算子 () は「関数」ではなく「関数へのポインタ」をオペランドとする

これを頭に入れて初めて,Cの宣言が「解読」できます.なお,英語の知識は仮定します.

int (*func_p)(double); を解読してみます.

  1. まず最初に,識別子に注目.
    func p is
  2. 括弧があるので,次は*に注目.
    func p is pointer to
  3. 関数を意味する () に行きます.引数は double.
    func p is pointer to function(double) returning
  4. 最後に,型指定子 int に行きます.
    func p is pointer to function(double) returning int
  5. 日本語に訳す.
    func p は,int を返す関数 (ちなみに引数は double) へのポインタ

int hoge[3][5]; は

  1. hoge の型は「int の配列 5 ,の配列 3」である.(要素数を配列の直後に示す)
  2. 式の中なので配列はポインタに読み替えられる.よって,hoge の型は「int の配列 5 へのポインタ」
  3. hoge[i] は*(hoge + i) のシンタックスシュガーである.

    (a) ポインタに i 加算することは,(そのポインタが指す型のサイズ)× i だけ,ポインタを進めることを意味する. hoge の指す先の型は「int の配列 5」であるから,hoge + i では,sizeof(int[5]) * i だけ進む.

    (b) *(hoge + i) の*により,ポインタが 1 つ剥がされる.*(hoge + i) の型は「int への配列 5」となる

    (c)式の中なので,配列がポインタに読み替えられる.*(hoge + i)の最終的な型は「intへのポインタ」となる.

  4. (*(hoge + i))[j] は,*((*(hoge + i)) + j) に等しい.したがって,(*(hoge + i))[j] は「int へのポイ ンタに j だけ加算したアドレスの内容」であり,型は int である.

最後に,int atexit(void (*func)(void)); の例も.

  1. atexit is
  2. atexit is function() returning
  3. atexit is function(func is) returning
  4. atexit is function(func is pointer to) returning
  5. atexit is function(func is pointer to function() returning) returning
  6. atexit is function(func is pointer to function(void) returning void) returning
  7. atexit is function(func is pointer to function(void) returning void) returning int

Wikipedia – 糖衣構文 も少し参考になります.

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中