2013-10-10 4 views
9

OK、私は噛んでしまいます。超人気Why does the C preprocessor interpret the word "linux" as the constant "1"?質問へanswer1987年Korn onelinerがUNIXを印刷するのはなぜですか?

main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}` 

プリント"unix"が、マクロ名のスペルとは全く関係がないの理由であることに言及しています。

私はhttp://www.ioccc.org/1987/korn.hintを読んで、私はかなりの詳細がこれをunobfuscating役立つだろうと思います:)

+5

この「質問」は質問ではなくパズルを示します。 –

+3

@EricPostpischilパズルは人々を困惑させ、人々が困惑すると質問をする傾向があります。 – glglgl

答えて

12

unixは、コンパイラまたは実行時環境の暗黙的な#defineのため1です。

したがって、および1["xy"] == "xy"[1]a[b] == b[a] == *(a + b)ので、したがって、あなたが得る:"%six\012\0"

  • (unix)["have"] = "have"[1] = 'a'

    • &unix["\021%six\012\0"]ポイント、
    • "'a'+"fun"-0x60" = "fun" + 1 = "un"

    これは、はっきりと印刷"unix\012"をしているprintf("%six\012\0", "un");にあなたを導き\012は、改行(\nと同じ)であること。

    unixが未定義の場合、e。 g。Windowsシステムでは、エラーが発生します。

    unix0(それが今までクリーンなシステム上の方法することができます?)だった場合は第二引数が"fun"+8ある場合、あなたはニルヴァーナを指していると、未定義の動作につながる、

    printf("\012%six\n", 'h'+"fun"-0x60) 
    

    を取得します。

  • 4

    通常、私はUnixライクなシステムの下でコンパイルされた場合にのみ、それは「UNIX」を印刷するべきだと思います。

    このようなシステムでは、unixの事前定義マクロで、値が1であるためです。

    main() { printf(&1["\021%six\012\0"], (1)["have"]+"fun"-0x60); } 
    

    int[array]ナンセンスを処分するために再注文し、我々が得る:

    main() { printf(&"\021%six\012\0"[1], "have"[1] + "fun"-0x60); } 
    

    それはスキップされていますので、我々は、(I'LLを\021を無視することができます

    このように、それはのように変換します?に置き換えて)\012\nに翻訳:

    main() { printf(&"?%six\n\0"[1], 'a' + "fun" - 0x60); } 
    main() { printf( "%six\n",  0x61 + "fun" - 0x60); } 
    
    与え

    main() { printf("%six\n", "un"); } 
    

    注:私は(特に第二部)に行ったとして、私はそれを解決再度ましたが、私はそれを見たのは初めてで、私も説明を理解するための2つのヒントを必要と

    • unix1
    • int[array]コンパイラが受け入れる実際の表記であることを意味します。
    関連する問題