关于C#:下面的表达式会输出什么?为什么?

What will be output of following expression and why?

1
printf(&unix["\021C%set"],(unix)["Chb"]+"Trick"-0X67);

它输出为"Cricket"。 但我无法理解为什么?
http://ideone.com/fTEAHG


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指针算术)。所以代码进一步简化了

1
printf("C%set","rick");

打印"板球"。


那么,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"。

所以我们留下:

1
printf("C%set","rick");

在"C"和"et"(Cricket)之间打印"rick"。