TOP >> マニアックなプログラミング
トリッキーコードネット トリッキーなコード

【芸術的な凄いプログラミング】IOCCC作品のコード解説2:「Unix」の表示

void main(void) {printf(&unix["\021%six\012\0"], (unix)["have"]+"fun"-0x60);}
↑のコードは、コンパイルして実行すると、"unix"と表示されます。(∩´∀`)∩(´∀`)∩(´∀`∩)ワショーイ!! このコードは、1987年のIOCCC優勝作品でもあり、WikipediaのIOCCC項目 で、一番最初に表示されているコードです。 また、こちらでは、より詳細にこのコードの解説をされている方がいるので、参考にして下さい^^;) 上記リンク先がなくなっていたので、私がコードの解説を書きます。 コードの解説に先立ち、もし上記コードをWindowsにて実行する場合は、以下の様にコード先頭に「#define unix 1」を書いてやる必要があります。 (∵ Unix環境では、unix が 1 と定義されている為)
#define unix 1 void main(void) {printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
さて、ではこのコードを、VC++2005で実行してみます。 以下の様な警告がでますが、コンパイルは可能です。 「warning C4013: 関数 'printf' は定義されていません。int 型の値を返す外部関数と見なします。」 実行結果は以下の通り IOCCCの作品解説:unixの表示 それでは、コードを読み解いて行きます。 まず、コードに適当な改行、インデントを入れます。そして、警告がうるさいのでstdio.hをインクルードします。
1 : #include <stdio.h> 2 : 3 : #define unix 1 4 : 5 : void main(void) 6 : { 7 : printf( 8 : &unix["\021%six\012\0"], 9 : (unix)["have"] + "fun" - 0x60 10 : ); 11 : }
そして、定義済のunixを1に置換します。
#include <stdio.h> void main(void) { printf( &1["\021%six\012\0"], (1)["have"] + "fun" - 0x60 ); }
そして、i["hogehoge"] が "hogehoge"[i] と同義だという、C言語の摩訶不思議な交換法則を適応します。
1 : #include <stdio.h> 2 : 3 : void main(void) 4 : { 5 : printf( 6 : &"\021%six\012\0"[1], 7 : "have"[1] + "fun" - 0x60 8 : ); 9 : }
さて、6行目はprintf()関数の第一パラメータであり、ここには char *が入ります。 "\021%six\012\0"という文字列の2文字目(配列は0-baseである事に注意)のアドレスを渡している為、 6行目全体は以下の文字列に置き換えられます。
"%six\012\0",
「%s」は、パラメータの文字列を差し込む位置、 「\012」は、8進数で「10」を表しており、これはアスキーコード表と照らし合わせると「\n(改行)」だと分かります。 「\0」は、おなじみのナル文字です。 これらを考慮し、最終的に6行目は、以下の様に置き換わります。
"%six\n",
つまり、冒頭のコード全体では、以下の様に置き換わります。
1 : #include <stdio.h> 2 : 3 : void main(void) 4 : { 5 : printf( 6 : "%six\n", 7 : "have"[1] + "fun" - 0x60 8 : ); 9 : }
次に、7行目を解析します。 「"have"[1]」の部分は、「'a'」を指しており、「'a'」をアスキーコード表を元に10進数に直すと「97」です。 そして、16進数表記の「0x60」を10進数に直すと「96」です。 つまり7行目は以下の様に置き換えられます。
97 + "fun" - 96
これは
"fun" + 1
ということであり、"fun"の2文字目のアドレスを指す事になります。つまり "un"のアドレスです。 以上を整理すると、冒頭のコードは
#include <stdio.h> void main(void) { printf( "%six\n", "un" ); }
となり、めでたく「unix」と表示される理由が判明しました~~♪^^;)
トリッキーコードネット の TOPへ HOTNEWS の 総合TOPへ