关于C语言中的'\?'和%% | 您所在的位置:网站首页 › c语言各种字符含义及符号表示 › 关于C语言中的'\?'和%% |
关于C语言中的'\?'和%%
一、引语 我们知道C/C++中有四个非字母的字符需要用转义字符来表示:单引号 ' , 双引号 " , 反斜杆 \ 和问号 ? 显然这是因为它们本身有特殊的含义,所以要用转义字符来表示他们自己,单引号'用来表示单个字符,双引号"用来表示字符串,反斜杆\是转义字符的标志,那么问号?呢,我们似乎想不出问号有什么特殊含义,它为什么还要用转义字符来表示它本身呢。 我们通过实验可以发现,不管是否使用转义字符,问号?都能准确地输出问号本身。 #include int main() { printf("question mark ? and escaped \?\n"); return 0;} 输出结果是:question mark ? and escaped ? 所以问号转义字符\?有什么存在的必要吗,为什么不用转义字符也能正常输出问号,甚至连一个编译警告都没有?
二、trigraph 为什么问号需要转义字符来表示它本身,显然是因为它确实是有特殊含义的。 我们先来了解一个词trigraph,trigraph是三字母词,又叫三连字。这个特性在现在是不受欢迎和极少使用的,但在早年条件艰苦的时候,我们的计算机键盘不像现在可以打出各种字符,所以就用三个字符连起来表示一个打不出的字符,具体如下: Trigraph: ??( ??) ??< ??> ??= ??/ ??' ??! ??- Replacement: [ ] { } # \ ^ | ~举个例子,下面是一个简单的C语言程序: #include int main() { printf("[]"); return 0;} 在早年键盘上没有那九个字符的时候,程序员们就这么写: ??=include int main() ?? 将 trigraph 替换成对应的字符发生在预处理之前,因此 trigraph 可以在源码中的任何位置都可以用,包括字符串内,函数体开头,预处理指令等。 实测中,codeblocks的GCC编译器默认不使用trigraph特性,当你代码中出现了以上三字母词时,会给出一个warning。如果有兴趣实验一下这个trigraph特性,可以在菜单栏中点击Settings -- Compiler -- Compiler settings -- Other compiler options,然后添加编译参数-trigraphs,即可使用trigraph特性。 言归正传,显然问号?是trigraph的一个标志,如我们要输出"??("时最好写成"\?\?(",防止编译器将其误解释为一个trigraph。
三、C语言标准允许问号?代表它本身 为什么不用转义字符\?也能准确输出?本身,因为C标准允许这么做 C11 §6.4.4.4 Character constants Section 4The double-quote " and question-mark ? are representable either by themselves or by the escape sequences \" and \?, respectively, but the single-quote ' and the backslash \shall be represented, respectively, by the escape sequences \' and \\. 上面这条标准说明了问号?和双引号"允许代表他们本身的字符,而单引号'和反斜杠\则必须用转义字符来表示他们本身的字符,可能有人会有疑问,在printf中不能单用"来输出双引号"啊,必须要用\",这是因为"在字符串中有特殊含义,不用转义字符就会产生冲突。如果我们输出单个字符putchar('"');则是允许的,不需要写putchar('\"'); 说明"是能代表它本身的。
四、关于printf中要用%%来输出一个%,而不是\% 我们知道对于本身有特殊含义的字符,要用转义字符来表示它本身,也知道%在printf中是格式说明符的一个标志,但其他转义字符都是前面加一个反斜杠\,%前面为什么是一个%。 实际上,%%与转义字符无关,它与printf如何处理格式说明符有关,转义字符对所有字符串有效,并在编译时完成,格式说明符(%)仅在一些函数使用,并在运行时使用。简而言之,在字符串或单个字符中,%都能代表它本身,不需要也不能用%%来表示一个%,只在像printf这样使用%作为格式说明符的函数中规定使用%%来明确表示一个%字符。 |
CopyRight 2018-2019 实验室设备网 版权所有 |