依然是直接抄书,,偶尔会自己写一段代码来演示,顺便对书的内容做些删减。参考书为:C Primer Plus。
Char类型
char类型用于存储字符(如,字母或标点符号),但是从技术层面看,char是整数类型,因为char类型实际上存储的是整数而不是字符。计算机使用数字编码来处理字符,即用特定的整数表示特定的字符。美国最常用的是ASCII码,在ASCII码中,整数65代表大写字母A。因此,存储字母A实际上存储的是整数65(许多IBM的大型主机使用另一种编码–EBDIC,其原理相同)。
标准ASCII码的范围是0~127,只需7位二进制数即可表示。通常,char类型被定义为8位的存储单元,因此容纳标准ASCII码绰绰有余。一般而言,C语言会保证char类型足够大,以存储系统(实现C语言的系统)基本字符。
许多字符集都超过了127, 甚至多于255。例如,日本汉字(kanji)字符集。商用的统一码(Unicode)创建了一个能表示世界范围内多种字符集的系统,目前包含的字符已超过110000个。国际标准化组织(ISO)和国际电工技术委员会(IEC)为字符集开发了ISO/IEC 10646标准。统一码标准也与ISO/IEC 10646标准兼容。
C语言把1字节定义为char类型占用的位(bit)数,因此无论是16位还是32位系统,都可以使用char类型。
声明char变量
char变量的声明与其他类型变量的声明方式相同。下面是一些例子:
1 |
|
字符常量和初始化
如果要把一个字符常量初始化为字母A, 不必背下ASCII码,用计算机语言很容易做到。通过以下初始化把字母A赋给grade即可:
1 | char grade = 'A'; |
在C语言中,用单引号括起来的单个字符被称为字符常量(character constant)。编译器一发现’A’,就会将其转换成相应的代码值。单引号必不可少。下面还有一些其他的例子:
1 | char broiled; // 声明一个char类型的变量 |
如上所示,如果省略单引号,编辑器认为T是一个变量名;如果把T用双括号括起来,编辑器则认为”T”是一个字符串。
实际上,字符是以数值形式储存的,所以也可使用数字代码值来赋值:
1 | char grade = 65; // 对于ASCII,这样做没问题,但是这是一种不好的编程风格 |
在本例中,虽然65是int类型,但是它在char类型能表示的范围内,所以将其赋值给grade没问题。由于65是字母A对应的ASCII码,因此本例是把A赋给grade。注意,能这样做的前提是系统使用ASCII码。其实,用’A’代替65才是较为妥当的做法,这样在任何系统中都不会出问题。因此最好使用字符常量,而不是数字代码。
奇怪的是,C语言将字符常量视为int类型而非char类型。例如,在int为32位,char为8位的ASCII系统中,有下面代码:
1 | char grade = 'B'; |
本来B对应的数值存储在32位的存储单元中,现在却可以存储在8位的存储单元中(grade)。利用字符常量的这种特性,可以定义一个字符常量’FATE’,即把4个独立的8位ASCII码存储在一个32位的存储单元中。如果把这样的字符常量赋给char类型变量grade, 只有最后八位有效。因此,grade的值是’E’。
非打印字符下面就不提了。因为这篇博客是纯手打,加上非打印字符的内容我就要累死了。。。
打印字符
printf()函数用%c指明待打印的字符。前面介绍过,一个字符变量实际上被存储为1字节的整数值。因此,如果用%d转换说明打印char类型变量的值,打印的是一个整数。而%c转换说明告诉printf()打印该整数值对应的字符。例如:
1 |
|
编译并执行:
1 | gcc test.c |
由此可知,printf()函数的转换说明决定了数据的显示方式,而不是数据的存储方式。
有符号还是无符号
有些C编译器把char实现为有符号类型,这意味着char可表示的范围是-128127。而有些编译器把char实现为无符号类型,那么char可表示的范围是0255。
根据C90标准,C语言允许在关键字char前面使用signed 或 unsigned。这样,无论编译器默认char是什么类型,signed char 表示有符号类型,而unsigned char表示无符号类型。这在用char类型处理小整数时很有用。如果只用char处理字符,那么char前面无需使用任何修饰符。