【发布时间】:2015-05-13 16:56:45
【问题描述】:
printf(&unix["\021C%set"],(unix)["Chb"]+"Trick"-0X67);
它的输出为“Cricket”。但我无法理解为什么? http://ideone.com/fTEAHG
【问题讨论】:
printf(&unix["\021C%set"],(unix)["Chb"]+"Trick"-0X67);
它的输出为“Cricket”。但我无法理解为什么? http://ideone.com/fTEAHG
【问题讨论】:
unix 是 predefined macro indicating it's a Unix-like system。
在 C 中,index[array] 与 array[index] 相同。正如MSDN所解释的那样:
通常postfix-expression所代表的值是一个指针值,比如数组标识符,expression是一个整数值(包括枚举类型)。但是,在语法上只需要一个表达式是指针类型,另一个是整数类型。因此整数值可以在 postfix-expression 位置,而指针值可以在表达式或下标位置的括号中。
所以
printf(&unix["\021C%set"],(unix)["Chb"]+"Trick"-0X67);
翻译成
printf(&"(\021C%set"[1]),"Chb"[1]+"Trick"-0X67);
&("\021C%set"[1])取“\021C%set”的第一个元素的地址,相当于取“C%set”的地址(由于C指针运算)。简化它,并重新排列一些操作数:
printf("C%set","Trick"+"Chb"[1]-0X67);
"Chb"[1] 是 'h',这是 ASCII 值 0x68,所以 "Chb"[1]-0X67 是 1,"Trick"+1 是 "rick"(由于 C 指针算法)。所以代码进一步简化为
printf("C%set","rick");
打印“Cricket”。
【讨论】:
&("\021C%set"[1])是"C%set"的地址吗?我没有完全理解你的解释。
"\021C%set"[1] 表示数组“\021C%set”的元素 1。元素1是'C'(因为元素0是'\021'),所以&("\021C%set"[1])是'C'的地址和"C%set"的地址。
\021 是什么意思?我认为这意味着空字符后跟 2,然后是 1。
嗯,unix 在这个实现中是 1。 a[b] 类似于*(a+b),a+b 类似于b+a,所以&unix["\021C%set"] 类似于&(*("\021C%set"+1))。由于&(*(c)) 或多或少只是c,这会得到"\021C%set"+1,它是指向第二个字符的指针,所以只需"C%set",它是“C”的格式字符串,后跟一个字符串“等”。 \021 是八进制转义符(长度为 1 到 3 个八进制数字;但许多有效),因此它只计为一个字符。
接下来我们有(unix)["Chb"],出于同样的原因,它与“Chb”[1]相同,它将是'h'字符的int值,在ASCII中是104。另一方面, 0X67 是 103。所以我们有 104+"Trick"-103 或 "Trick"+1。这与左侧使用的字符串文字的指针运算相同,它让你“rick”。
所以我们只剩下:
printf("C%set", "rick");
在“C”和“et”(板球)之间打印“rick”。
【讨论】: