#include<stdio.h>
int 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");
}
return 0;
}
这是一个C代码,它根据给定字符串中的第三个字符给出输出。 “AB”“CD”给出Casabance,“AB”“DD”给出了Blood Diamond。 我想知道switch语句中的表达式是如何计算的?
虽然,我尝试了另一个代码,
#include<stdio.h>
int main()
{
const char ch=*(1+"AB""AD"+1);
printf("%c",&ch);
return 0;
}
此代码为我对字符串所做的任何更改提供输出'f'。 我想知道如何评估这个表达式?
为什么以上两个代码都不同?
答案 0 :(得分:2)
这里有一个重要的错误
#include <stdio.h>
int main()
{
const char ch = *(1 + "AB""AD" + 1);
printf("%c", &ch);
/* ^ WRONG ... */
return 0;
}
您正在通过char *
预期char
,这将调用未定义的行为。传递与相应说明符不匹配的参数时,printf()
函数族不会定义行为。
在这种情况下,参数是一个指针,所以
printf("%p", (void *) &ch);
会打印ch
的地址,但如果要打印字符,请执行
printf("%c", ch);
此外,1 + "AB""CD" + 1
并且原谅我写一个荒谬的写作方式"ABCD" + 2
它没有错,而且它100%有效,但它会让你思考为什么,为什么有人会浪费时间这样做?
答案 1 :(得分:2)
在此切换语句中
switch(*(1+"AB""CD"+1))
首先是字符串文字&#34; AB&#34;和&#34; CD&#34;由编译器连接,结果看起来像
switch(*(1+"ABCD"+1))
字符串文字存储为以零结尾的字符数组。例如,在C字符串中,文字"ABCD"
具有类型char[5]
(在C ++中,字符串文字具有常量字符数组的类型。因此在C ++中,字符串文字"ABCD"
具有类型const char[5]
)。< / p>
在表达式中,数组被隐式转换为指向数组的第一个字符的指针。
因此在这个表达式1+"ABCD"+1
中可以更简单地编写,如
2+"ABCD"
或
"ABCD" + 2
使用了所谓的指针算法。表达式的结果是指向字符串文字的第三个元素并且类型为char *
的指针。
因此,应用解除引用会得到字符串文字的第三个字符。
在此代码段中
const char ch=*(1+"AB""AD"+1);
printf("%c",&ch);
使用了类型ch
的相同字符串文字和对象const char
,它由字符串文字的相同第三个字符初始化。
然而在声明中
printf("%c",&ch);
您正在尝试将对象的地址输出为字符。编写
是正确的printf( "%c", ch );