下面的表达式会输出什么,为什么?
What will be output of following expression and why?
printf(&unix["1C%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 所解释的:
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.
所以
printf(&unix["1C%set"],(unix)["Chb"]+"Trick"-0X67);
转换为
printf(&"(1C%set"[1]),"Chb"[1]+"Trick"-0X67);
&("1C%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."
好吧,unix
在这个实现中是 1。 a[b]
类似于 *(a+b)
,a+b
类似于 b+a
,因此 &unix["1C%set"]
类似于 &(*("1C%set"+1))
。由于 &(*(c))
或多或少只是 c
,这会得到 "1C%set"+1
,它是指向第二个字符的指针,所以只是 "C%set"
,它是 "C" 后跟一个字符串,然后是 "et"。 1
是一个八进制转义符(长度为 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"。
printf(&unix["1C%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 所解释的:
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.
所以
printf(&unix["1C%set"],(unix)["Chb"]+"Trick"-0X67);
转换为
printf(&"(1C%set"[1]),"Chb"[1]+"Trick"-0X67);
&("1C%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."
好吧,unix
在这个实现中是 1。 a[b]
类似于 *(a+b)
,a+b
类似于 b+a
,因此 &unix["1C%set"]
类似于 &(*("1C%set"+1))
。由于 &(*(c))
或多或少只是 c
,这会得到 "1C%set"+1
,它是指向第二个字符的指针,所以只是 "C%set"
,它是 "C" 后跟一个字符串,然后是 "et"。 1
是一个八进制转义符(长度为 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"。