11

よし、噛むぞ。Cプリプロセッサが「 linux 」という単語を定数「1」と解釈するのはなぜですか? 質問はそれを述べています

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

が表示"unix"されますが、マクロ名のスペルとはまったく関係のない理由によります。

私はhttp://www.ioccc.org/1987/korn.hintを読みましたが、より詳細な情報が難読化を解除するのに役立つと思います:)

4

2 に答える 2

14

unix#defineコンパイラまたはランタイム環境で暗黙的であるため、1です。

したがって、したがって、a[b] == b[a] == *(a + b)したがって1["xy"] == "xy"[1]、次のようになります。

  • &unix["\021%six\012\0"]に指差す"%six\012\0"
  • (unix)["have"] = "have"[1] = 'a'
  • "'a'+"fun"-0x60" = "fun" + 1 = "un".

これにより、改行である print が明確に表示されます(と同じprintf("%six\012\0", "un");) 。"unix\012"\012\n

unixが定義されていない場合(Windows システムなど)、エラーが発生します。

unixだった場合0(クリーンなシステムでそれが可能でしょうか?)、次のようになります。

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

ここで、2 番目の引数は"fun"+8であり、涅槃を指し、未定義の動作につながります。

于 2013-10-10T14:42:11.047 に答える
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); }

はスキップされているので無視し\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 番目の部分) 再解決していましたが、最初に見たとき、説明を理解するために 2 つのヒントが必要でした。

  • unix意味1
  • int[array]コンパイラが受け入れる実際の表記です。
于 2013-10-10T14:40:26.957 に答える