6. 字符类型与字符编码

字符型常量或变量也可以参与运算,例如:

printf("%c\n", 'a'+1);

执行结果是b

我们在第 1 节 “程序和编程语言”讲过,计算机之所以能处理符号,是因为符号在计算机内部也用数字来表示,每个字符在计算机内部都用一个整数来表示,称为字符编码(Character Encoding),目前大部分平台通用的是ASCII码(American Standard Code for Information Interchange,美国信息交换标准码),详见图 A.1 “ASCII码表”。表中每一栏的最后一列是字符,前三列分别是用十进制(Dec)、十六进制(Hx)和八进制(Oct)表示的字符编码,有关各种进制之间的换算以后再讲,从十进制那一列可以看出ASCII码的取值范围是0~127。表中的很多字符是不可见字符(Non-printable Character)和空白字符(Whitespace)[5],不能像'a'这样把字符本身填在表中,而是要用一个名字来表示,例如CR(carriage return)LF(NL line feed,newline)DEL等等。作为练习,请读者查一查表 2.1 “C标准规定的转义字符”中的字符都在ASCII码表的什么位置。

回到刚才的例子,在ASCII码中字符'a'是97,字符b是98。'a'+1这个表达式,根据隐式类型转换规则要把字符型转成整型再做计算,也就是把'a'按ASCII码转成整型的97,然后加1,得到98,现在表达式的值是一个整型,而printf却以%c的格式打印它,于是printf把这个整数当作ASCII码来解释,打印出相应的字符'b'。

之前我们说“整型”是指int型,而现在我们知道char型本质上就是整数,只不过取值范围比int型小,所以以后我们把char型和int型统称为整数类型(Integer Type)或简称整型。其实还有几种我们没学到的类型也属于整型,我们将在第 15 章 数据类型详解总结一下整型包括哪些类型。

在ASCII码表中,字符'a'~'z'、'A'~'Z'、'0'~'9'的ASCII码都是连续的,例如'a'+1和'b'的值相等,'0'+9和'9'的值相等。注意'0'~'9'的ASCII码是十六进制的30~39,这是字符型'0'~'9'和整数0~9的区别。

字符也可以用ASCII码的转义序列表示,这种表示可以用在字符常量或字符串字面值中,例如'\0'表示NUL字符,'\11'或'\x9'表示Tab字符,"\11"或"\x9"表示由Tab字符组成的字符串。这种转义序列由\加上1~3个八进制数字组成,或者由\x(大写的\X也可以)加上1~2个十六进制数字组成。



[5] Whitespace在不同的上下文中有不同的含义,在C语言中Whitespace定义为空格、水平Tab、垂直Tab、换行和分页符以及这些字符的某些组合,本书在使用Whitespace这个词时会明确说明指的是哪些字符。