2008年9月3日水曜日

【例解UNIX】Cの復習(2):ポインタ、バイトオーダ、複雑な型 (その2)

こつこつ。バイトオーダから。

  • リトルエンディアン:x86, MIPS
  • ビッグエンディアン:SPARC, MIPS
  • 「改行と文字コードの問題を除けば、テキストデータはとても移植性の高いデータ表現です」

  • 続いてtypedef。
  • Cには4つのタグ名がある。

    • goto文のラベル名
    • タグ名 (構造体、共用体、enum)
    • メンバ名
    • その他(変数名、関数名、型定義名)
    • 列挙定数名

  • う、5つに見えるのだが。
  • typedefの例。

    • typedef struct list list
    • listがstruct list。これは違和感なし。
    • typedef int Array[10]
    • Arrayがint [10]。違和感あり。
    • typedef int (*Func)(int)
    • Funcがint (*) (int)。違和感おおきい。

  • Array hogeがint hoge[10]ということだから、関数型マクロみたいなものと思っておくか。


  • そうか、システムデータ型の確認にはgdbが便利だ。

  • うぉー、Cの型宣言、難しすぎ。
  • int (*(*foo[])())[];
  • int の配列へのポインタを返す関数へのポインタの配列。(笑った)



    • int (*(*foo[])())[];

      分解しながら。

      int hoge; hogeはint。
      int hoge[]; hogeはintの配列。
      int (hoge)[];
      int (*hoge)[]; hogeはintの配列のポインタ。
      int (*hoge())[]; hogeはintの配列のポインタを返す関数。
      int (*(*hoge)())[]; hogeはintの配列のポインタを返す関数のポインタ。
      int (*(*hoge[])())[]; hogeはintの配列のポインタを返す関数のポインタの配列。

    • おお。一応読めた。
    • signalのプロトタイプを読む。

      void (*signal (int sig, void (*handler)(int)))(int);

      最左の識別子のみが重要。ここから考える。
      void ( *signal (int sig, void (*handler) (int) ) ) (int);

      *signal()を間違えないように *(signal())とする。
      void ( *(signal (int sig, void (*handler) (int) ) ) ) (int);

      読む。
      void hoge; hogeはvoid。
      void hoge (int); hogeはvoidを返す関数(引数はint)。
      void (*hoge) (int); hogeはvoidを返す関数(引数はint)へのポインタ。
      void (*(hoge (piyo)) (int); hogeはvoidを返す関数(引数はint)へのポインタを返す関数(引数piyo)。
      void (*(hoge (int sig, void (*handler)(int))) (int); hogeはvoidを返す関数(引数はint)へのポインタを返す関数(引数は、intと、voidを返す関数(引数int)へのポインタ)。
      こんな感じじゃろう。


  • 演習問題2.13

    • int *x1(); intへのポインタを返す関数。
    • int (*x2)(); intを返す関数へのポインタ。
    • int *(x3()); intへのポインタを返す関数。
    • int (*x4()); intへのポインタを返す関数。

  • お、読めた。
  • 関数の型もgdbのptypeでわかるのね。それぞれ、

    • int *()
    • Int (*)()

  • 演習問題2.14

    • int *x5[]; intへのポインタの配列
    • int (*x6)[]; intの配列へのポインタ
    • int *(x7[]); intへのポインタの配列
    • int (*x8[]); intへのポインタの配列

  • gdb.

    • int *[1]
    • int (*)[0]

  • う、1とか0がなぜいるのかわからない。

最後、ぐだぐだになったが、ビット演算まで終わった。
次回は可変長引数から。

0 件のコメント: