切换案例表达式

时间:2016-07-16 07:19:20

标签: c switch-statement

考虑表达式*(1+"AB" "CD"+1)

这个表达的解决方案是什么?上面的表达式是C中的开关表达式。

*(2+"AB" "CD") --> *(2+"ABCD") --> ?

在此之后该怎么办? 以下是代码段:

#include<stdio.h>
void main(){
     switch(*(1+"AB" "CD"+1)){
        case 'A':printf("Pulp Fiction");
                  break;
        case 'B':printf("12 Angry Man");
                  break;
        case 'C':printf("Casabance");
                  break;
        case 'D':printf("Blood Diamond");
     }

}

3 个答案:

答案 0 :(得分:6)

Casabance。

如果你有

char *cp;
int i;

然后cp[i] == *(cp+i) == *(i+cp) == i[cp]

C11 6.5.2.1:

  

后缀表达式后跟方括号[]中的表达式   是数组对象元素的下标。该   下标运算符[]的定义是E1 [E2]与...相同   (*((E1)+(E2)))。

和C11 6.5.6:

  

添加或减去具有整数类型的表达式时   从指针开始,结果具有指针操作数的类型。如果   指针操作数指向数组对象的元素和数组   足够大,结果指向一个偏离的元素   原始元素使得下标的差异   结果和原始数组元素等于整数表达式。

就编译器而言,字符串文字只是一个char指针。

彼此相邻的两个字符串文字自动连接成一个字符串文字:

C11 6.4.5:

  

在翻译阶段6中,指定的多字节字符序列   任何相邻字符序列和相同前缀字符串   文字标记连接成一个多字节字符   序列

所以... *(1+"AB" "CD"+1) == *(1+"ABCD"+1) == *("ABCD"+1+1)==*("BCD"+1) == "BCD"[1] == 'C'

答案 1 :(得分:3)

运行你的代码,你会得到答案“Casabance”

  • "AB" "CD"等于"ABCD"
  • *("ABCD")指向'A'
  • *("ABCD" + 0)指向'A'
  • *("ABCD" + 1)指向'B'
  • *("ABCD" + 2)指向'C'
  • 'C'回答是“Casabance”

答案 2 :(得分:1)

以下是不同步骤的说明,全部在编译时执行:

  • 字符串文字序列"AB" "CD"在编译时连接成单个字符串文字"ABCD"
  • 此字符串文字将编译为5 char的数组,使用值'A''B''C''D'和{{1}初始化}。
  • 在表达式'\0'中,数组衰减为指向其第一个元素的指针,所述指针递增2指向第三个元素,在本例中为1 + "ABCD" + 1字节。
  • 取消引用此指针的计算结果为Cchar
  • switch表达式具有常量值'C',转换为'C',尽管它不是C标准定义的常量表达式
  • 编译器可能会将int优化为使用字符串switch的{​​{1}}一次调用,因为可以在http://gcc.godbolt.org/#上验证

请注意,示例中printf的原型不正确,应为"Casabance"main或等效。此外,在int main(void)块的最后int main(int argc, char *argv[])break;子句的末尾省略case是容易出错的。

相关问题