今天因为对C语言三字符(trigraphs)的无知而吃了一堑。
事情是这样的:
在keil uVsion5.25中建了一个很简单的工程,编译的时候报了一个warning:
在帮助文档里并没有找到和#2532-D相关的信息 。一开始怀疑是不是用了破解版软件的问题。在词典里查了trigraph 这个单词,但是没往三字母方面想。经过一番VC后,终于发现了一篇文章也提及了#2532-D:support for trigraphs is disabled 。
看到这篇文章中提及了三字符的概念,才明白warning的原因。(原文链接:http://www.eepw.com.cn/article/256102.htm后)
因为注释问题报警还是第一次遇到。之前也从来没有关注转义字符和三字符的相关知识。
C语言中的三字母词(trigraph)
在ANSI C标准中,定义了9个三字母词(trigraph),三字母词就是几个字符的序列,合起来表示另一个字符。三字母词使C语言环境可以在缺少一些必需字符的字符集(比如,一些非常老式的键盘上没有[]{}#\^~|)上实现。也许是由于这些字符集我们基本上用不到,所以在大多数C语言的书籍中,我们都看不到对三字母词的讲解。下图列出了9个三字母词以及它们所代表的的字符。
源代码中的“三字母词”,在编译阶段会被替换为“对应的字符”。对于以“?”开头的字符序列,如果不能与上面9个匹配,编译器将保持原状;一旦匹配,编译器就会做替换。 下面是我们很容易犯的一个错误(摘自《C和指针》):
如果我们想在屏幕上输出字符串"(are you ok??)"时,
printf("%s\n", "(are you ok??)");
由于编译器对于三字母词的处理所以导致我们看到的结果如下图所示:
注意:由于编译器的种类各样,对ANSI C的支持也不一样,所以可能会有些C编译器不处理“三字母词”,会将它们当做普通的字符串来处理。以上测试时我在VS2008编译环境下完成的
所以这个时候大家应该要问了,那到底应该如何打印出我们想要的字符串呢??方法也很简单,代码如下:
printf("%s\n", "(are you ok\?\?\)");
这次的测试结果如下图:
我们来看一下一些转义字符变:
注意:其他的转义字符较为常见,这里要重点说的是最后两个:
1."\ddd"字符'\'后面代表的是八进制数字,举个例子:
printf("%c\n", '\060');
‘060’的十进制结果应该是48,我们以字符形式输出,则48是字符‘0’的ASCLL码值。结果如下图所示:
2."\xddd"字符'\'后面代表的是三个十六进制数,举个例子:
printf("%c\n", '\x030');
‘0x030’的十进制结果也是48,所以输出结果也是‘0’。