关于C之ASCII码与转义字符

ASCII码:

ASCII是基于拉丁字母的一套电脑编码系统。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。共定义了128个字符,其中33个字符无法显示(这是以现今操作系统为依归,但在DOS模式下可显示出一些诸如笑脸、扑克牌花式等8-bit符号),且这33个字符多数都已是陈废的控制字符。控制字符的用途主要是用来操控已经处理过的文字,在33个字符之外的是95个可显示的字符。

ASCII控制字符(33个):

二进制十进制十六进制缩写可以显示的表示法名称/意义
0000 0000000NUL空字符(Null)
0000 0001101SOH标题开始
0000 0010202STX本文开始
0000 0011303ETX本文结束
0000 0100404EOT传输结束
0000 0101505ENQ请求
0000 0110606ACK确认回应
0000 0111707BEL响铃
0000 1000808BS退格
0000 1001909HT水平定位符号
0000 1010100ALF换行键
0000 1011110BVT垂直定位符号
0000 1100120CFF换页键
0000 1101130DCR归位键
0000 1110140ESO取消变换(Shift out)
0000 1111150FSI启用变换(Shift in)
0001 00001610DLE跳出数据通讯
0001 00011711DC1设备控制一(XON 启用软件速度控制)
0001 00101812DC2设备控制二
0001 00111913DC3设备控制三(XOFF 停用软件速度控制)
0001 01002014DC4设备控制四
0001 01012115NAK确认失败回应
0001 01102216SYN同步用暂停
0001 01112317ETB区块传输结束
0001 10002418CAN取消
0001 10012519EM连接介质中断
0001 1010261ASUB替换
0001 1011271BESC跳出
0001 1100281CFS文件分割符
0001 1101291DGS组群分隔符
0001 1110301ERS记录分隔符
0001 1111311FUS单元分隔符
0111 11111277FDEL删除

ASCII可显示字符(95个):

二进制十进制十六进制图形
0010 00003220(空格)␠
0010 00013321!
0010 00103422"
0010 00113523#
0010 01003624$
0010 01013725 %
0010 01103826&
0010 01113927'
0010 10004028(
0010 10014129)
0010 1010422A*
0010 1011432B+
0010 1100442C,
0010 1101452D-
0010 1110462E.
0010 1111472F/
0011 000048300
0011 000149311
0011 001050322
0011 001151333
0011 010052344
0011 010153355
0011 011054366
0011 011155377
0011 100056388
0011 100157399
0011 1010583A:
0011 1011593B;
0011 1100603C<
0011 1101613D=
0011 1110623E>
0011 1111633F?
 
二进制十进制十六进制图形
0100 00006440@
0100 00016541A
0100 00106642B
0100 00116743C
0100 01006844D
0100 01016945E
0100 01107046F
0100 01117147G
0100 10007248H
0100 10017349I
0100 1010744AJ
0100 1011754BK
0100 1100764CL
0100 1101774DM
0100 1110784EN
0100 1111794FO
0101 00008050P
0101 00018151Q
0101 00108252R
0101 00118353S
0101 01008454T
0101 01018555U
0101 01108656V
0101 01118757W
0101 10008858X
0101 10018959Y
0101 1010905AZ
0101 1011915B[
0101 1100925C\
0101 1101935D]
0101 1110945E^
0101 1111955F_
 
二进制十进制十六进制图形
0110 00009660`
0110 00019761a
0110 00109862b
0110 00119963c
0110 010010064d
0110 010110165e
0110 011010266f
0110 011110367g
0110 100010468h
0110 100110569i
0110 10101066Aj
0110 10111076Bk
0110 11001086Cl
0110 11011096Dm
0110 11101106En
0110 11111116Fo
0111 000011270p
0111 000111371q
0111 001011472r
0111 001111573s
0111 010011674t
0111 010111775u
0111 011011876v
0111 011111977w
0111 100012078x
0111 100112179y
0111 10101227Az
0111 10111237B{
0111 11001247C|
0111 11011257D}
0111 11101267E~

上表中对应的十进制数没有负值,char的取值范围:-2^7~2^7-1(-128~127),非负的char范围:0~127(标准字符集)。

控制字符都是要加ctrl控制键来完成控制的,不+ctrl键是无法起作用的,输出单个控制字符啥也没有。

比如Ctrl+Z这种在windows/Linux下表示的文件结尾符,可以表示为'\032'(八进制)。最新DOS都不用结尾符而是用文件大小来判断结尾的。

其实char也是有扩展空间的,对于unsigned char类型范围是0~255,所以有扩展ASCII字符如下:

我们的讨论还是基于非扩展ASCII字符(标准字符集)的情况下:

在C中,char实质上是以int存储的,char<->int可互相转换(前提当然不能超过char取值范围0~127,char是不为负值的signed类型)。

#include <stdio.h>
int main() {
  char ch = '!';
  int i = 33;
  printf("%d,%c\n", ch, i);
  return 0;
}
33,!

由此可见,char可直接转换为int型值,int也可直接转换为char字符(查表可知十进制33对应可显字符为感叹号 ! )。 

char的实质是int存储,所以对于任意字符char ch; ch+N对应的就是ch后数第N个字符。而数字或字母都是从小到大连续的,所以7+'0'='7','a'+5='e'。。。

我们来仔细看一下字符和整数相加和转换的过程:

Int(0~9) + '0' = Int(0~9) + Int(48) = Int(48~57)<=>Char('0'~'9'),即:(0~9) + '0' = ('0'~'9')。

可以看到,首先是字符转化为相应的int型数字,然后两数字相加,最后再转化为相应的字符。

要想把一个0~9的整数i直接转换为一个char类型,直接+'0'即可。如:

int i = 2;
char ch = 2 + '0';

这样就直接ch='2'了,当然前提条件是:0 =< i <= 9。其实不+'0'操作也没什么两样和实际的作用,这里只是展示例子而已。

11+'0'=? => Int(11)+Int(48)=Int(59)=';'

转义字符:

所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。

转义字符

意义

ASCII码值(十进制)

\a

响铃(BEL)

007

\b

退格(BS) ,将当前位置移到前一列

008

\f

换页(FF),将当前位置移到下页开头

012

\n

换行(LF) ,将当前位置移到下一行开头

010

\r

回车(CR) ,将当前位置移到本行开头

013

\t

水平制表(HT) (跳到下一个TAB位置)

009

\v

垂直制表(VT)

011

\\

代表一个反斜线字符''\'

092

\'

代表一个单引号(撇号)字符

039

\"

代表一个双引号字符

034

\?代表一个问号063

\0

空字符(NUL)

000

\ddd

1到3位八进制数所代表的任意字符

三位八进制

\xhh

十六进制所代表的任意字符

十六进制

由于ASCII中的33个字符多数都已是陈废的控制字符,而严格意义上转义字符并不是控制字符,但有几个字符有控制字符的意味在里面。

比如要发出一个系统响铃,可以这样定义字符:

char beep1 = 7; // 可以这样做
char beep2 = '\a'; // 也可以这样做
char beep3 = '\007'; // 还可以这样做(如果'\a'不能被编译器识别,就可以用ASCII码替代)

由于所有ASCII码都可以用“\”加数字(一般是8进制数字)来表示,如果要打印#号,尝试下面代码:

#include <stdio.h>
int main() {
  char ch = 35;
  char ch1 = '\035'; <-代表int型29:3×8 + 5 = 29
  char ch2 = '\0x23'; // Warning:Implicit conversion from 'int' to 'char' changes value from 7877171 to 51
  printf("%c,%c,%c,%c\n", ch, ch1, ch2, ch);
  return 0;
}
#,,3,#

分析输出:十进制35<->ASCII码#,ch输出正常。ch1要注意是八进制而不是十进制表示,所以应该这样:char ch1 = '\043';才能正确输出#号,由于默认是八进制,也可以去掉0写成ch1='\43'。至于ch2,'\0x23'原本想用十六进制表示值,但这行不能,'\'只解析八进制。经尝试发现规律:令ch2='\0ijk' (其中i,j,k是任意数字或字母),总是输出最后指定的k;这里就不再去细究了。总之,用'\0xx'这种八进制的格式可以去表达所有ASCII码。

一般转义字符是随printf()、fprintf()这样的函数一起输出的。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itzyjr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值