7.1 转义字符的示例
什么叫转义字符呢?假设我们要在屏幕上打印一下 c: \ code \ test.c,或者是其他的都行,比如我们再打印一下 c: \ test \ test.c,那这句话到底能不能被打印出来呢?如图所示:
它打印出来的结果,好像并没有 \t,这是什么原因导致的呢?这个地方其实就是转义字符的原因,本来我们这个地方一个 \ 加一个 t。\ 就是 \,t 就是 t,两个字符
但实际上你会发现打印出来的时候也没有 \ 和 t 呢?没有。\t 空白出了一片,因为这个 \ 和 t 不再是一个字符 \ 和一个字符 t 的意思了,它们转变了它们原来的意思,所以叫转义字符。转义字符就是转变了它原来的意思。本来我们的一个 \ ,一个 t,就是一个 \,一个 t 来的,现在现在不是了,它转义成其他意思了
再比如,我们再打印一下双引号 ab\ncd,这个地方本来应该是 ab 打印完之后,打印一个 \,一个 n,一个 \ 一个 n 是两个字符,再加上一个 c,一个 d。但是你会发现,当我们打印出来的时候,其实不是这个效果。那是什么原因?
因为 \ 和 n 也不再是一个 \,一个 n 的意思了,而是一个换行。它也转变意思了,变成一种叫换行的意思。因此,\n 也是一种转义字符,它不再是一个普通的 \ 加 n 的这样一个组合,而是一个转义字符,这就是转义字符的来源,转义字符就是转变了这个字符原有的意思,如图所示:
7.2 转义字符都有哪些
C 语言里边的转义字符都有哪些呢?一共有13种转义字符,如图所示:
1. \? 在书写连续多个问号时使用,防止他们被解析成三字母词
2. \' 用于表示字符常量'
3. \'' 用于表示一个字符串内部的双引号
4. \\ 用于表示一个反斜杠
5. \a 警告字符,蜂鸣
6. \b 退格符
7. \f 进纸符
8. \n 换行
9. \r 回车
10. \t 水平制表符
11. \v 垂直制表符
12. \ddd ddd 表示1-3个八进制的数字,如:\130 X
13. \xdd dd 表示2个十六进制数字,如:\x30 0
\b,\f,\v 也没什么大的用,至今我都没有用过
12. \ddd 和 \xdd 是非常特殊的存在
7.2.1 \?
\? 这就是一个转义字符,但是这个转义字符现在不好验证了,因为现在很多的编译器都不支持三字母词了。三字母词是什么意思呢?C 语言里边把这种 ?? 开头,2个 ? 开头加上一个小圆括号,就会被解析成一个方括号的
也就是说,??) 这三个字母组合起来,其实是一个方括号],这是我们之前在 C 语言里边的一个概念叫三字母词
三字母词出现的时候我们需要注意一下:如果 ??) 被解析成一个 ] 的话,假设有一个人就想输出 are you ok?? 这样一个信息,然后两边一个括号,中间是??。假设人家就想打印这个东西,你会发现打印不出来了,因为这个??) 总是会被解析成一个 ],如图所示:
那怎么办呢?当然是转义字符,让第一个 ? 不再是三字母词里的 ?,让第二个 ? 不再是三字母词里的 ?,在前面加 \ 就可以了,第一个 \ 就把第一个 ? 转义一下,第二个 \ 就把第二个 ? 转义一下,这样的话,打印出来的永远都是 ??),如图所示:
在有一些编译器底下,比如说早期的 VC6.0底下,你会发现:你去测试这句话的时候,你会发现看不到这个 ??)的,你会看到一个 ],即用 VC6.0去测试的话,它最终打印出的结果是这样的:(are you ok],这是 \? 这种转义字符的场景,但是这个东西,不一定能够验证出来了,现在的编译器可能不支持了
7.2.2 \'
\' 它也是一种转义字符,这种转义字符应用到什么场景呢?举个例子,我们打印一下 printf("%c\n", 'a'),%c 是打印字符,打印一个字符 a,然后屏幕上打印了一个 a,没有任何问题,如图所示:
a 可以打印的话,那我们打印一个单引号,我想在屏幕上打印一个单引号,这样行不行呢?我们两个单引号其实括一个字符 a 是没有任何问题的,但是两个单引号里边括个单引号,这样行不行呢?这就出问题了,如图所示:
前面两个单引号会认为是一对单引号里的打印好,而后面的单引号就落单了。所以出现了问题,那我希望这就是一个普普通通的单引号,就不要再是一对单引号里的单引号了,怎么办呢?我们让它转义,加个 \ 就可以了,这个时候这个单引号就是普普通通的一个字符了,我们屏幕上就输出了一个单引号,如图所示:
7.2.3 \''
当然,\'' 也是一个道理,如果给个 printf("%s\n", "abc"),如图所示:
补充:
%s 是用来打印字符串的
打印 ? 不需要转义成 \? 再打印
printf 在打印数据的时候,可以指定打印的格式,举例如下:
1. printf("%d", 100) 中的 %d 这个意味着我们指定打印一个整型,打印个100
2. 如果要打印一个字符,那是怎么指定的呢?printf("%c\n", 'a'),这就是打印字符 a
3. 而如果想打印字符串,它的指定是什么呢?printf("%s\n", "abc")
" " 之间是 ',就不用加 \ 了,因为它不会组成一对双引号的概念,这个单引号不会和前面的、后面的双引号组成一对
字符串里边只打印一个字符 a,也是可以的(第163行代码),如图所示:
字符 a 换成双引号,我们打印一个双引号,字符串里边放一个双引号,这个时候又出问题了(第164行代码),如图所示:
前面这两个双引号会被解析成一对双引号,后面一个双引号就落单了,所以我们希望中间的这个双引号它只是一个普通的双引号字符,它不是一对双引号里的双引号,怎么办呢?让它转义(第164行代码)。如图所示:
7.2.4 \\
有人就好奇了,这个 \\ 是什么意思?我们再来回忆一下,我们最开始 c: \ test \ test.c 这句话没法打印,没法打印的原因是因为 \t 也是个转义字符(\t 叫水平制表符,什么是水平制表符呢?如果你注意的话,水平制表符就是我们键盘上的 tab)
既然 \t 是个水平制表符的话,它被解析成一个水平制表符的话,就是 prtinf("c: est est.c"),它不会在这个地方打印 \t 的,怎么办呢?我不想让这个 \ 是 \t 里的 \,所以我就让它转义,如图所示:
7.2.5 \a
\a 我们可以在自己电脑上测试一下,\a 也是一种转义字符,但是它是一种警告字符,它会出声音的,比如 printf("\a") 的时候,电脑就会响一下
一个 \a 其实会让电脑响一下,它会触发你的电脑上的蜂鸣,写几个 \a 就会有几声响
7.2.6 \ddd
有两种转义字符非常特殊,一种叫 \ddd,这个不是 \ 后面跟3个 d,而是 ddd 表示1-3个八进制数字,如:\130,我们发现结果是一个 X,为什么是大写的 X 呢?\ 后面跟着的这3个数字是八进制,那么八进制的130是十进制的多少呢?是88。
对于一个八进制数字来说,如果它是130,一个八进制数字假设是130的话,
这个0,它是最低位,它的权重是8的0次方
这个3,它是第二位,它的权重是8的1次方
这个1,它是第三位,它的权重是8的2次方
对于十进制,我们举个例子,十进制的130,那为什么中间的3是30呢?如果这个数字是十进制,它这个1的权重是多少呢?1的权重是10的2次方;3的权重是10的1次方;0的权重是10的0次方。因此,1*10的2次方 + 3*10的1次方 + 0*10的0次方 = 100+30+0 = 130,所以十进制的130代表的就是130
所以八进制代表的130就是1*8的2次方 + 3*8的1次方 + 0*8的0次方 = 88,也就是说,130这个八进制数字,最后转化成十进制其实是88,那最终打印的 X 和88有什么关系呢?其实 X 的 ASCII 码值就是88
因此:当\130 是个字符的时候,是把130这个八进制数字转换成十进制数字所得的这个88,作为 ASCII 码值代表的那个字符。如图所示:
我们也可以反过来测,假设我们想打印出来 A,A 的 ASCII 码值是65,十进制的65转化成八进制是多少呢?是101。pritnf("%d\n", '\101'),这就是 A
\ 后面跟上3个数字,其实是一个转义字符,就是把这个八进制数字转换成十进制之后,以它为 ACSII 码值代表的那个字符。如图所示:
7.27 \xdd
\xdd:\ 后面跟个 x,x 后面跟两个数字,这两个 dd 表示两个十六进制数字,如 printf("%c\n", '\x30'),同理,3是第二位,它的权重是16的1次方;0是最低为,它的权重是16的0次方。
因此,1*16的1次方 +0*16的0次方 = 48,48作为 ASCII 码值代表的那个字符是0。打印的是字符0,我们用%c 打印的,不是用 %d,而如果用 %d 打印的话,那是数字0。如图所示:
7.28 ASCII 码值
其实我们键盘上可以敲出各种各样的字符,哪些字符呢?比如 @ !E R 1这都是字符,内存中存储的是二进制,计算机存储的是二进制,计算机能够理解的是二进制
而这些字符该怎么存储呢?比如 A,这个时候有人就提出来了:我们这些字符存储的时候不好存储,没关系,我们给这些字符编个号,比如 A 我们编个65,B 编个66,a 编个97,b 编个98,按照这样,给每一个字符都编了一个号,最后产生了一个东西叫 ASCII 码表。在 ASCII 码表里边,给每一个字符都规定了一个值,这个值就叫做 ASCII 码值,如图所示:
7.3 面试题之求字符串长度
我们现在已经知道 strlen 能够求字符串长度,比如:pritnf("%d\n", strlen("abc")),长度是3,因为 a 一个,b 一个,c 一个,然后后面遇到 \0了,当后面有个隐藏的 \0 的时候,说明是字符串的结束标志
然后我们就不再往后数了,字符串结束了,所以 strlen 去求它的长度的时候就是3,在 \0 之前有 abc 3个字符,所以是3。如图所示:
求一下这个字符串的长度,如图所示:
补充:
\328数的时候,不敢把它当成一个,因为八进制数字里边哪有八呢?没有,最大才为7。所以不数进去,\32才算一个转义字符,8是一个独立字符
八进制数字里边没有8,它是0-7组成的,所以这个地方不可能出现8,而一旦出现8,就不是八进制数字了,就不可能是 \ 连续的3个数字