今日は、C言語の意外かもしれない仕様をいくつか。

配列の添え字のように見えるもの a[b] と書くと配列演算をしているような気分になるが、式の中に表れる a[b]は、(*( (a) + (b) ) ) の略記であり、ポインタの計算と何も変わるところがない*1。

というわけで： int a[] = {1,2,3,5,8}; int b[2][2]={{1,2},{5,9}}; a[3]=100; printf( "%d

", 3[a] ); /* 3[a] は、*(3+a)なので、a[3] と同じ*/ b[1][0]=999; printf( "%d == %d

", 1[b][0], 0[1[b]] ); /* どちらも b[1][0] と同じ */ となる。

(foo()?a:b)[3] と書くよりも 3[foo()?a:b] と書いた方が短くなるので、ソースコードを1文字でも短くしようというゲームに参加している人は知っていると役に立つことがあるかもしれない。

そうでない人の役には立たないと思う。

typedef は先頭に書かなくてもいい これを知ったときは非常に驚いた。実は、typedef は先頭に書かなくてもいい。例えば以下の通り： unsigned typedef char foo; /* たぶん正しいが、マイクロソフトコンパイラではエラー */ printf( "%d

", (int)(foo)-1 ); /* y は unsigned char なので、255 が出力される */ g++ は、私の意図通りにコンパイルするが、マイクロソフトはエラーにしてくれる。エラーにしてくれた方がいいと思う。