好的,我来翻译。一个回答为什么C预处理器会把单词"linux"解释为常量"1"?的问题提到:
它是对这个极受欢迎的问题的回答。main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}`
引用块: 打印出
"unix"
,但与宏名称的拼写绝对没有任何关系。段落: 我读了http://www.ioccc.org/1987/korn.hint,但我认为更详细的内容会有助于理解这个代码的含义。
好的,我来翻译。一个回答为什么C预处理器会把单词"linux"解释为常量"1"?的问题提到:
它是对这个极受欢迎的问题的回答。main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}`
"unix"
,但与宏名称的拼写绝对没有任何关系。unix
的值为1,是由于编译器或运行环境中隐式定义了#define
。
因此,由于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
未定义,例如在Windows系统上,你会收到一个错误。
如果unix
的值为0
(在干净的系统上可能吗?),你会得到
printf("\012%six\n", 'h'+"fun"-0x60)
第二个参数是"fun"+8
,指向涅槃,并导致未定义的行为。
通常情况下,我认为只有在类Unix系统下编译时才应该打印出“unix”。
这是因为在这样的系统中,“unix”是一个预定义宏,其值为1。
因此,它被翻译为:
main() { printf(&1["\021%six\012\0"], (1)["have"]+"fun"-0x60); }
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]
是编译器实际接受的符号。