关于C语言中的'\?'和%%

一、引语

我们知道C/C++中有四个非字母的字符需要用转义字符来表示:单引号 ' , 双引号 " , 反斜杆 \ 和问号 ?

显然这是因为它们本身有特殊的含义,所以要用转义字符来表示他们自己,单引号'用来表示单个字符,双引号"用来表示字符串,反斜杆\是转义字符的标志,那么问号?呢,我们似乎想不出问号有什么特殊含义,它为什么还要用转义字符来表示它本身呢。

我们通过实验可以发现,不管是否使用转义字符,问号?都能准确地输出问号本身。

#include <stdio.h>

int main() {
    printf("question mark ? and escaped \?\n");

return 0;
}

输出结果是:question mark ? and escaped ?

所以问号转义字符\?有什么存在的必要吗,为什么不用转义字符也能正常输出问号,甚至连一个编译警告都没有?

二、trigraph

为什么问号需要转义字符来表示它本身,显然是因为它确实是有特殊含义的。

我们先来了解一个词trigraph,trigraph是三字母词,又叫三连字。这个特性在现在是不受欢迎和极少使用的,但在早年条件艰苦的时候,我们的计算机键盘不像现在可以打出各种字符,所以就用三个字符连起来表示一个打不出的字符,具体如下:

Trigraph:       ??(  ??)  ??<  ??>  ??=  ??/  ??'  ??!  ??-
Replacement:      [    ]    {    }    #    \    ^    |    ~

举个例子,下面是一个简单的C语言程序:

#include <stdio.h>

int main() {

    printf("[]");

return 0;
}

在早年键盘上没有那九个字符的时候,程序员们就这么写:

??=include <stdio.h>

int main() ??<
    printf("??(??)");

return 0;
??>

将 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 4

The 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这样使用%作为格式说明符的函数中规定使用%%来明确表示一个%字符。

转载于:https://www.cnblogs.com/kangkang-/p/9405826.html

关于C语言中的'\?'和%%相关推荐

  1. c语言中struct和c++中class实例对比

    前言 实现游戏中简单的打怪升级的功能 c语言中的struct #include <stdio.h>typedef void(*Train)(struct player*, int); ty ...

  2. 关于C语言中printf函数“输出歧视”的问题

    目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...

  3. C语言中“野指针”、“悬空指针”是什么?

    目录 1."野指针"(wild pointer) 2."悬空指针"(dangling pointer) 1."野指针"(wild point ...

  4. c+语言+null,C/C++语言中NULL、'\0’和0的区别

    NULL.'\0'和0的值是一样的,都是0,不过它们的表现形式不一样: 1. NULL: 即空指针,不过在C和C++中并不一样.在VS 2013的库文件string.h中可以看到如果定义. 1 /* ...

  5. 关于C语言中的malloc和free函数的用法

    一.malloc()和free()的基本概念以及基本用法: 1.函数原型及说明: void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针 ...

  6. python global函数_如何使用python语言中的global关键字获取函数值

    在python语言中,如果在函数外层定义了一个全局变量a,函数内部又有一个同名的局部变量,想要这个全局变量的值改成为局部变量的值,可以使用global.下面利用一个实例说明如何实现这个场景,操作如下: ...

  7. c语言中的if语句_If ... C中的其他语句解释

    c语言中的if语句 Conditional code flow is the ability to change the way a piece of code behaves based on ce ...

  8. C 语言中 void* 详解及应用介绍

    void 在英文中作为名词的解释为 "空虚.空间.空隙",而在 C 语言中,void 被翻译为"无类型",相应的void * 为"无类型指针" ...

  9. java 英文字符 字节_3、在JAVA语言中,每个英文字符占 个字节,每个中文汉字占( )个字节。...

    [判断题]中心原子中的几个原子轨道杂化时,必形成数目相同的杂化轨道. [单选题]集合 用区间表示正确的是 ( ) [单选题]15.Java语言的类间的继承关系是 [单选题]8.编译Java Appli ...

  10. 8位alu运算器(vhdl语言)_C语言中signed char类型,能表示-128到127,为什么负数多一位?...

    初学者在学习C语言,谈到不同数据类型时,一般都能理解 unsigned 和 signed 的区别,无非就是有无符号而已.但是对于 signed 数据类型的数据范围,初学者却常常会感到迷惑. 对于 si ...

最新文章

  1. 41-高级路由:BGP AS长度:接收一切、最大AS长度、不比较AS长度
  2. vue 删除页面缓存_vue项目强制清除页面缓存的例子
  3. Dataset之JFT:JFT/FastEval14k数据集的简介、下载、案例应用之详细攻略
  4. 绝对定位多个字居中显示的css
  5. 智能对话引擎:两天快速打造疫情问答机器人
  6. 贪心法——区间覆盖问题
  7. [zz] 使用ssh公钥密钥自动登陆linux服务器
  8. oracle Client 11g静默安装
  9. 第四章 ASP.NET MVC HTML.ActionLink输出超链接的具体用法
  10. 如何在 Pr 中创建动作序列?
  11. html 隐藏广告代码大全,JS广告代码_JS广告代码大全_js特效代码_js特效代码大全 - 懒人建站...
  12. ssm框架整合springSecurity
  13. 4071 国际象棋(枚举)
  14. Mac键盘符号说明(全)
  15. Ubports安装和使用gedit和ros等记录(仅供参考)
  16. 洗地机排名前十的产品、洗地机品牌排行榜最新公布
  17. 一套完整的Android通用框架
  18. 数据结构期末考试——选择题
  19. 品铂平板电脑刷linux,教你如何把品铂PIPO W8平板电脑升级到win10系统
  20. JS计算数组各数据所占百分比

热门文章

  1. 解决阿里云 ssh 远程连接短时间没操作就会断掉的问题
  2. react 日历组件_anujs1.5.1支持React.Suspense与lazy
  3. c 中头文件和源文件的区别是什么
  4. C语言 | 指向指针的指针排序
  5. 如何设置网件gs108e_Netgear 网件 EAX80 AX6000规格 无线扩展器 开箱拆解评测
  6. html选择器有哪些child,css3选择器child有哪些?css3选择器child用法详解
  7. php模块安装 pdo_mysql_关于php插件pdo_mysql的安装
  8. 光端机的几种物理接口类型
  9. 【渝粤题库】陕西师范大学500018 物理实验研究 作业(专升本)
  10. 【渝粤题库】广东开放大学 婚姻家庭法 形成性考核