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

关于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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mockito 使用_用Mockito回答

mockito 使用在编写单元测试时 &#xff0c;必须记住不要依赖于外部组件。 为了避免这种情况&#xff0c;我们使用了模拟框架&#xff0c;对我而言&#xff0c;最容易使用的是Mockito 。 在本文中&#xff0c;我们将看到在Mockito中使用的一种“高级”技术&#xff0c;可以使用…

jQuery常用操作

jQuery jQuery是一个轻量级的JS库&#xff0c;是一个被封装好的JS文件&#xff0c;提供了更为简便的元素操作方式&#xff0c;jQuery封装了DOM。 使用jQuery 引入jQuery文件 <scrtipt srcjquery-1.11.3.js> </script> 注意&#xff1a;引入必须放在其他jQuery操作之…

python tab和空格混用_我的 Python 编码规范

python 文件的组成为了便于描述&#xff0c;先上一个 demo#!/usr/bin/env python# -*- coding: utf-8 -*-"""通常这里是关于本文档的说明(docstring)&#xff0c;须以半角的句号、 问号或惊叹号结尾!本行之前应当空一行&#xff0c;继续完成关于本文档的说明如果…

Twitter创始人Jack Dorsey的每日必做和不做清单

Twitter创始人Jack Dorsey显然是这段时间以来技术界的中心人物&#xff0c;不仅发表了一系列的文章&#xff0c;而且一本反映Twitter早期岁月的书也即将出版。今天&#xff0c;他又在Y Combinator的Startup School上发表了讲话&#xff0c;不过在谈话中Dorsey回避了一切不必要及…

JSR-308和Checker框架为jOOQ 3.9添加了更多类型安全性

Java 8引入了JSR-308&#xff0c;它为Java语言添加了新的注释功能。 最重要的是&#xff1a;键入注释。 现在可以像下面这样设计怪物了&#xff1a; 比注解更疯狂的是类型注解。 在数组上。 谁认为这是有效的Java代码&#xff1f; pic.twitter.com/M9fSRRerAD — Lukas Eder&…

Linux NTP服务配置 for Oracle RAC

安装Oracle 11g RAC时&#xff0c;我们需要配置ntp服务。在使用虚拟机的情况下对于时钟同步方式的配置有很多种方式&#xff0c;可以使用vmware自带的时钟同步功能&#xff0c;也可以直接将本地的一个节点用作时间服务器。本文介绍直接配置ntp方式的时钟服务器。1、查看两节点的…

java字符编码方式总结

java字符编码方式总结一、概要在JAVA应用程序特别是基于WEB的程序中&#xff0c;经常遇到字符的编码问题。为了防止出现乱码&#xff0c;首先需要了解JAVA是如何处理字符的&#xff0c;这样就可以有目的地在输入/输出环节中增加必要的转码。其次&#xff0c;由于各种服务器有不…

按键扫描

unsigned char Trg,cont,num;void key_sm(void) { uchar Read;ReadP0^0xff;TrgRead&(Read^cont);contRead; } void key_hs(){  switch(Trg)   {     case 0x01:       num;     break;     case 0x02:       num--;     break;     d…

Mathematica函数大全

一、运算符及特殊符号 Line1; 执行Line&#xff0c;不显示结果 Line1,line2 顺次执行Line1&#xff0c;2&#xff0c;并显示结果 ?name 关于系统变量name 的信息 ??name 关于系统变量name 的全部信息 !command 执行Dos 命令 n! N 的阶乘 !!filename 显示文件内容 <<fi…

oem是代工还是贴牌_食用油OEM贴牌代工业务要注意哪些问题?

近年来食用油OEM业务逐渐增加&#xff0c;OEM是英文 Original Equipment Manufacturer的缩写&#xff0c;被译为代工生产或贴牌生产&#xff0c;通常是指品牌商委托有生产能力且品质有保证的油脂加工厂来生产食用油产品&#xff0c;对自己及对方的品牌不会有冲突&#xff0c;且…

java 简化判断_简化Java内存分析

java 简化判断作为一名典型的Java开发人员&#xff0c;除了遵循关闭连接&#xff0c;流等典型的最佳实践外&#xff0c;我从未监视过应用程序的内存使用情况。最近&#xff0c;我们在JBoss服务器中遇到了一些问题&#xff0c;不得不深入研究内存管理Java中最好的事情之一是&…

DRF的序列化组件

rest rest下的url url唯一代表资源&#xff0c;http请求方式来区分用户行为 url的设计规范 GET&#xff1a; 127.0.0.1:9001/books/       # 获取所有数据 GET: 127.0.0.1:9001/books/{id}      # 获取单条数据 POST&#xff1a; 127.0.0.1:9001/books/      # 增…

15crmo焊接后多长时间探伤_承压设备渗透探伤检测方法简单操作思路

啥是渗透检测渗透检测俗称渗透探伤&#xff0c;是一种以毛细管作用原理为基础用于检查表面开口缺陷的无损检测方法。它与射线检测、超声检测、磁粉检测和涡流检测一起&#xff0c;并称为5种常规的无损检测方法&#xff0c;渗透检测始于本世纪初&#xff0c;是目视检查以外最早应…

SpringBoot实战(五)之Thymeleaf

Thymeleaf同jsp、volocity、freemarker等共同的职能是MVC模式中的视图展示层&#xff0c;即View。 当然了&#xff0c;SpringBoot中也可以用jsp,不过不推荐这种用法&#xff0c;比较推崇的就是使用Thymeleaf。 关于Thymeleaf学习&#xff0c;建议参考官方文档:https://www.thym…

Arrays.sort()

今天在做一个按更新时间搜寻出某个文件夹里面的所有文件&#xff0c;由于自己写算法比较花费时间&#xff0c;干脆就用j2se提供的类Arrays提供的sort&#xff08;&#xff09;方法&#xff0c;这样就比较省力。对于基本数据类型只要Arrays.sort(数组)[“注&#xff1a;数组是声…

Thymeleaf 3 – Thymeleaf 3和Spring MVC快速入门

Thymeleaf 3发布到达。 新版本带来了许多新功能&#xff0c;例如HTML5支持以及不带标记的文本模板支持– [# th:utext"${thymeleaf.version}" /] &#xff0c;改进的内联功能– <p>Thymeleaf [[${thymeleaf.version}]] is great!</p> &#xff0c;性能改…

rmi远程代码执行漏洞_【最新漏洞简讯】WebLogic远程代码执行漏洞 (CVE202014645)

↑ 点击上方“SecMind安全管家”关注我们 情报编号&#xff1a;W1120200715漏洞概述WebLogic是Oracle公司出品的用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器&#xff0c;全球使用广泛。WebLogic的远程方法调用RMI通信使用T3协议&#…

python 的内存回收,及深浅Copy详解

一、python中的变量及引用1.1 python中的不可变类型&#xff1a;数字(num)、字符串(str)、元组(tuple)、布尔值(bool<True,False>) 接下来我们讲完后你就懂了为什么它们是不可变对象了。 都知道python中一切都是对象&#xff0c;而变量就是这些对象的引用&#xff0c;什么…

不是技术牛人,如何拿到国内IT巨头的Offer

不久前&#xff0c;byvoid面阿里星计划的面试结果截图泄漏&#xff0c;引起无数IT屌丝的羡慕敬仰。看看这些牛人&#xff0c;NOI金牌&#xff0c;开源社区名人&#xff0c;三年级开始写Basic...在跪拜之余我们不禁要想&#xff0c;和这些牛人比&#xff0c;作为绝大部分技术屌丝…