2016年2月24日水曜日

【Linux】 構造体配列の初期化のやりかた 【初めてのC】

最近Linuxの話題が多いです.

わたしはソフト屋ではないので他人が書いたプログラムを読む場面が基本的に無い人なのですが、最近はLinux moduleのソースコードをチラチラと読んでいる場面が基本的に多い人になっていると云っても過言ではありません.

Kernelソースを見ていると、なんじゃこの記述は?これって本当にC言語の文法なの?という場面があります.わたしが未熟なだけですが.

↓①たとえばこれ
#define FUNC(a)  [a]={.num=a,.name=#a}

これはマクロなのだろうなぁとはわかる.だがしかし#aってなんだろう? C言語の文法に#変数なんて無いですから.

ひとしきりCの文法を検索してあきらめて、マクロを調べたら「#変数」はマクロの文法でした.
どこかで
  #define  a   12345
と定義されていたとする.それで、
  num = a
の場合は変数numに数字の12345が代入される.しかし、
  name = #a
の場合は、文字列nameに文字配列の”12345”が代入されるのだそうです.

マクロはあまり使わないからなぁ、知らないのも無理はないか.


↓②この構造体の初期化はタイポかと最初は思いました.
struct xxx yyy = {
        .name   = a ,
        .age    = b ,
        .height = c , };
末尾の「 , 」がタイポかと思ったところでした.だって関数の引数の末尾にカンマを打ったりしたらコンパイル時にerror stopしますから.
そうしたらこのカンマの意味は、構造体xxxには他にもメンバーが存在し、ここで明示しなかったメンバーにはNULLを代入する、という意味なのだそうです.


↓③構造体配列の初期化で、こんな解説はよく見かけますが、
struct xxx yyy[] = { { “Taro”, 16, 156 },
                     { “Jiro”, 17, 173 },
                     { “Nana”, 18, 168 } };

↓④構造体配列の初期化で、こんなのは知らないやり方でした.う~んと唸ってうずくまってしまいました.配列yyy[n]を呼び出して、しかも任意の順番で初期化できるなんて聞いてないよー.
struct xxx yyy[] = { { [5].name = “Taro” },
                     { [0].name = “Jiro” },
                     { [2].name = “Nana” }, };

↓⑤構造体配列の初期化には他にも一癖あります.
struct xxx yyy[] = { [5] = { “Taro”, 16, 156 },
                     [0] = { “Jiro”, 17, 173 },
                     [2] = { “Nana”, 18, 168 }, };
④を知ってたら⑤もアリだなと思いますけど、最初にこの⑤の記述を見て面食らって、あれこれ調べたら④だの③だの②だのと芋づる式に出てきました.

構造体の初期化には知らないことがいろいろあるようです.こんなことでは書籍「初めてのC」をエロ本と勘違いしていた友人を嗤えませんな.まぁこの書名はわざとだろと思いますが.

ちなみに、①②③は日本語のサイトに解説がありましたが、④⑤は日本語サイトでは見つからず、英語サイトで解説を見つけました.日本人の解説屋にはもっとがんばって重箱の隅までチクチクと説明して欲しいと思いました.


かしこ


人気ブÍグランキングへ

0 件のコメント:

コメントを投稿