IOCCC 1987 by David Korn
kshの人のワンライナーの仕組みを今日初めて知った。そっか、こういう仕組みか!
#include <stdio.h> int main() { mainの最初に(暗黙に)定義されたint変数 ANSI CじゃなくてK&R Cなのがポイント。つまりargc、すなわち起動パラメータが無ければ1 printf("unix=%d\n", unix); 文字列の先頭アドレスをインクリメントするので"un"が表示される printf("%s\n","fun"+1); 2文字目がintとして評価されるから97 printf("%d\n", "have"[1]); 上はこれと等価 printf("%d\n", 'a'); x[y] = *(x+y) = y[x] だから、こうも書ける printf("%d\n", (1)["have"]); 97 - 96 = 1 printf("%d\n", (1)["have"] - 0x60); 第2引数は"fun" + 1 と等価だから'un'が表示される printf("%s\n", "fun" + ( (1)["have"] - 0x60) ); 括弧をとって、変数unixを使った。これも等価 printf("%s\n", (unix)["have"]+"fun"-0x60); さて、これは'bcde'が表示される printf("%s\n", "abcde" + 1); こうも書ける。この場合&には意味がない printf("%s\n", &"abcde"[1]); これも等価 printf("%s\n", &(1)["abcde"]); 括弧をはずしたが、優先順位があるので結果は変わらず printf("%s\n", &unix["abcde"]); 2文字目から表示。だから'%six'+改行文字 printf("%s", &"?%six\n"[1]); 2文字目から表示。だから'%six'+改行文字(\012)。最後の\0は無視される printf("%s", &"\021%six\012\0"[1]); これも等価。'%six'+改行文字(\012) printf("%s", &unix["\021%six\012\0"]); 上をフォーマット文字列に使ったので、'ABix'+改行文字が表示される printf(&unix["\021%six\012\0"], "AB"); やってることはこれと一緒 printf("%six\n", "AB"); じゃあ、"AB"のかわりに"un"を使えば printf("%six\n", (unix)["have"]+"fun"-0x60); "unix"が表示されるじゃないか printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60); return 0; }
解説無かったらわかんないよ!