ASCII码:
ASCII是基于拉丁字母的一套电脑编码系统。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。共定义了128个字符,其中33个字符无法显示(这是以现今操作系统为依归,但在DOS模式下可显示出一些诸如笑脸、扑克牌花式等8-bit符号),且这33个字符多数都已是陈废的控制字符。控制字符的用途主要是用来操控已经处理过的文字,在33个字符之外的是95个可显示的字符。
ASCII控制字符(33个):
二进制 | 十进制 | 十六进制 | 缩写 | 可以显示的表示法 | 名称/意义 |
---|---|---|---|---|---|
0000 0000 | 0 | 00 | NUL | ␀ | 空字符(Null) |
0000 0001 | 1 | 01 | SOH | ␁ | 标题开始 |
0000 0010 | 2 | 02 | STX | ␂ | 本文开始 |
0000 0011 | 3 | 03 | ETX | ␃ | 本文结束 |
0000 0100 | 4 | 04 | EOT | ␄ | 传输结束 |
0000 0101 | 5 | 05 | ENQ | ␅ | 请求 |
0000 0110 | 6 | 06 | ACK | ␆ | 确认回应 |
0000 0111 | 7 | 07 | BEL | ␇ | 响铃 |
0000 1000 | 8 | 08 | BS | ␈ | 退格 |
0000 1001 | 9 | 09 | HT | ␉ | 水平定位符号 |
0000 1010 | 10 | 0A | LF | ␊ | 换行键 |
0000 1011 | 11 | 0B | VT | ␋ | 垂直定位符号 |
0000 1100 | 12 | 0C | FF | ␌ | 换页键 |
0000 1101 | 13 | 0D | CR | ␍ | 归位键 |
0000 1110 | 14 | 0E | SO | ␎ | 取消变换(Shift out) |
0000 1111 | 15 | 0F | SI | ␏ | 启用变换(Shift in) |
0001 0000 | 16 | 10 | DLE | ␐ | 跳出数据通讯 |
0001 0001 | 17 | 11 | DC1 | ␑ | 设备控制一(XON 启用软件速度控制) |
0001 0010 | 18 | 12 | DC2 | ␒ | 设备控制二 |
0001 0011 | 19 | 13 | DC3 | ␓ | 设备控制三(XOFF 停用软件速度控制) |
0001 0100 | 20 | 14 | DC4 | ␔ | 设备控制四 |
0001 0101 | 21 | 15 | NAK | ␕ | 确认失败回应 |
0001 0110 | 22 | 16 | SYN | ␖ | 同步用暂停 |
0001 0111 | 23 | 17 | ETB | ␗ | 区块传输结束 |
0001 1000 | 24 | 18 | CAN | ␘ | 取消 |
0001 1001 | 25 | 19 | EM | ␙ | 连接介质中断 |
0001 1010 | 26 | 1A | SUB | ␚ | 替换 |
0001 1011 | 27 | 1B | ESC | ␛ | 跳出 |
0001 1100 | 28 | 1C | FS | ␜ | 文件分割符 |
0001 1101 | 29 | 1D | GS | ␝ | 组群分隔符 |
0001 1110 | 30 | 1E | RS | ␞ | 记录分隔符 |
0001 1111 | 31 | 1F | US | ␟ | 单元分隔符 |
0111 1111 | 127 | 7F | DEL | ␡ | 删除 |
ASCII可显示字符(95个):
|
|
|
上表中对应的十进制数没有负值,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()这样的函数一起输出的。