main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}`
打印
"unix"
,但原因与宏名称的拼写完全无关。
我读过http://www.ioccc.org/1987/korn.hint,但我认为更多细节会有助于不加协商:)
答案 0 :(得分:12)
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"
。这会引导您printf("%six\012\0", "un");
显然打印"unix\012"
,\012
是换行符(与\n
相同)。
如果unix
未定义,e。 G。在Windows系统上,您会收到错误。
如果unix
是0
(这可能是干净系统的方式吗?),那么
printf("\012%six\n", 'h'+"fun"-0x60)
其中第二个参数是"fun"+8
,指向Nirvana并导致未定义的行为。
答案 1 :(得分: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"); }
注意:我正在重新解决它(特别是第二部分),但是第一次看到它时我需要两个提示来理解解释:
unix
表示1
int[array]
是编译器接受的实际表示法。