What will be output of following expression and why?
1
| printf(&unix ["\021C%set"],(unix )["Chb"]+"Trick"-0X67); |
它输出为"Cricket"。 但我无法理解为什么?
http://ideone.com/fTEAHG
-
密切相关:stackoverflow.com/q/19210935/827263
unix是一个预定义的宏,表明它是类Unix系统。
在C中,index[array]与array[index]相同。正如MSDN所解释的那样:
Usually, the value represented by postfix-expression is a pointer value, such as an array identifier, and expression is an integral value (including enumerated types). However, all that is required syntactically is that one of the expressions be of pointer type and the other be of integral type. Thus the integral value could be in the postfix-expression position and the pointer value could be in the brackets in the expression or subscript position.
所以
1
| printf(&unix ["\021C%set"],(unix )["Chb"]+"Trick"-0X67); |
翻译成
1
| printf(&"(\021C%set"[1]),"Chb"[1]+"Trick"-0X67); |
&("\021C%set"[1])获取" 021C%set"的第一个元素的地址,这相当于取"C%set"的地址(由于C指针算术)。简化,并重新排列一些操作数:
1
| printf("C%set","Trick"+"Chb"[1]-0X67); |
"Chb"[1]是'h',它是ASCII值0x68,因此"Chb"[1]-0X67是1,"Trick"+1是"rick"(由于C指针算术)。所以代码进一步简化了
打印"板球"。
-
你能澄清为什么&("\021C%set"[1])是"C%set"的地址吗? 我没有完全理解你的解释。
-
@DanielKleinstein - C字符串是字符数组。 所以"\021C%set"[1]表示数组" 021C%set"的元素1。 元素1是'C'(因为元素0是' 021'),所以&(" 021C%set"[1])是'C'的地址和"C%set"的地址。
-
\021是什么意思? 我认为这意味着空字符后跟2然后是1。
-
@DanielKleinstein - 这是一个八进制转义序列。
那么,unix在这个实现中是1。 a[b]类似于*(a+b),a+b类似于b+a,所以&unix["\021C%set"]类似于&(*("\021C%set"+1))。由于&(*(c))或多或少只是c,这会得到"\021C%set"+1,它是指向第二个字符的指针,所以只有"C%set",这是"C"的格式字符串,后跟一个字符串,后跟"ET"。 \021是一个八进制转义符(长度为1到3个八进制数;但是很多有效数),因此它只计为一个字符。
接下来我们有(unix)["Chb"],出于同样的原因与"Chb"[1]相同,它将是'h'字符的int值,在ASCII中是104.另一方面,0X67是103.所以我们有104+"Trick"-103或"Trick"+1。这是左侧使用的字符串文字的相同指针算法,它让你"rick"。
所以我们留下:
在"C"和"et"(Cricket)之间打印"rick"。