Antigloss 最后修改于 2006-12-23
1. 字符型(char)简介
字符型(char)用于储存字符(character),如英文字母或标点。严格来说,char 其实也是整数类型(integer type),因为 char 类型储存的实际上是整数,而不是字符。计算机使用特定的整数编码来表示特定的字符。美国普遍使用的编码是 ASCII(American Standard Code for Information Interchange 美国信息交换标准编码)。例如:ASCII 使用 65 来代表大写字母 A,因此存储字母 A 实际上存储的是整数65。注意:许多IBM大型机使用另一种编码——EBCDIC(Extended Binary-Coded Decimal Interchange Code 扩充的二进制编码的十进制交换码);不同国家的计算机使用的编码可能完全不同。
ASCII 的范围是 0 到 127,故而 7 位(bit)就足以表示全部 ASCII。char 一般占用 8 位内存单元,表示ASCII绰绰有余。许多系统都提供扩展ASCII(Extended ASCII),并且所需空间仍然在 8 位以内。注意,不同的系统提供的扩展 ASCII 的编码方式可能有所不同!
许多字符集超出了 8 位所能表示的范围(例如汉字字符集),使用这种字符集作为基本字符集的系统中,char 可能是 16 位的,甚至可能是 32 位的。总之,C 保证 char 占用空间的大小足以储存系统所用的基本字符集的编码。C 语言定义一个字节(byte)的位数为 char 的位数,所以一个字节可能是 16 位,也可能是 32 位,而不仅仅限于 8 位。
2. 声明字符型变量
字符型变量的声明方式和其它类型变量的声明方式一样:
char good;
char better, best;
以上代码声明了三个字符型变量:good、better,和 best。
3. 字符常量与初始化
我们可以使用以下语句来初始化字符型变量:
char ch = 'A';
这个语句把 ch 的值初始化为 A 的编码值。在这个语句中,'A' 是字符常量。C 语言中,使用单引号把字符引起来就构成字符常量。我们来看另外一个例子:
char fail; /* 声明一个字符型变量 */
fail = 'F'; /* 正确 */
fail = "F"; /* 错!"F" 是字符串字面量 */
把字符用双引号引起来构成字符串字面量,所以第三个语句是错误的。我们会在后续的教程中讨论字符串,现在暂且把它放下。
因为字符实质上是以数字的形式存储的,所以我们可以直接使用数字来初始化字符变量,或者给字符变量赋值:
char ch = 65; /* 不好的风格 */
在 ASCII 中,A 的编码是 65,所以对于使用 ASCII 的系统来说,这个语句等同于 char ch = 'A';。使用非 ASCII 的系统中,65 代表的不一定是 A,而有可能是其它任何字符,所以使用数字来初始化字符变量,或者给字符变量赋值是一种不好的风格,因为移植性太差了!但是,使用字符常量(例如 'A')来初始化字符变量,或者给字符变量赋值,字符变量得到的一定是我们所期待的字符的编码值。例如:
char ch = 'A';
无论在使用任何编码的系统中,ch 都能够得到字符 A 所对应的编码值。这是因为编译器会自动把 'A' 转化成 A 所对应的编码值。因此,我们应该使用字符常量来初始化字符变量,或者给字符变量赋值;而不要用数字。
有趣的是,C 使用 int 类型来处理字符常量,而不是 char 类型。例如,在使用32位 int 的ASCII 系统中,以下代码
char ch = 'C';
'C' 的编码值 67 被存储于 32 位的内存单元中;不过 ch 仍然存储于 8 位的内存单元中,只是它的值变成了 67。因此,我们可以定义形如 'good' 的古怪字符常量。因为每个字符的编码值占用 8 位的内存单元,所以这个常量刚好可以存储于 32 位的内存单元。然而,用这种字符常量初始化字符变量,或者给字符变量赋值的话,导致的结果是,字符变量只能得到字符常量的最后 8 位。也就是说,以下代码
char ch = 'good';
ch 得到的是 'd' 的值。
以后,在没有特殊说明的情况下,我们讨论的都是 ASCII。
ASCII 表
| ASCII值 |
控制字符 |
ASCII值 |
控制字符 |
ASCII值 |
控制字符 |
ASCII值 |
控制字符 |
| 0 |
NUL |
32 |
(space) |
64 |
@ |
96 |
` |
| 1 |
SOH |
33 |
! |
65 |
A |
97 |
a |
| 2 |
STX |
34 |
" |
66 |
B |
98 |
b |
| 3 |
ETX |
35 |
# |
67 |
C |
99 |
c |
| 4 |
EOT |
36 |
$ |
68 |
D |
100 |
d |
| 5 |
ENQ |
37 |
% |
69 |
E |
101 |
e |
| 6 |
ACK |
38 |
& |
70 |
F |
102 |
f |
| 7 |
BEL |
39 |
' |
71 |
G |
103 |
g |
| 8 |
BS |
40 |
( |
72 |
H |
104 |
h |
| 9 |
HT |
41 |
) |
73 |
I |
105 |
i |
| 10 |
LF |
42 |
* |
74 |
J |
106 |
j |
| 11 |
VT |
43 |
+ |
75 |
K |
107 |
k |
| 12 |
FF |
44 |
, |
76 |
L |
108 |
l |
| 13 |
CR |
45 |
- |
77 |
M |
109 |
m |
| 14 |
SO |
46 |
. |
78 |
N |
110 |
n |
| 15 |
SI |
47 |
/ |
79 |
O |
111 |
o |
| 16 |
DLE |
48 |
0 |
80 |
P |
112 |
p |
| 17 |
DC1 |
49 |
1 |
81 |
Q |
113 |
q |
| 18 |
DC2 |
50 |
2 |
82 |
R |
114 |
r |
| 19 |
DC3 |
51 |
3 |
83 |
S |
115 |
s |
| 20 |
DC4 |
52 |
4 |
84 |
T |
116 |
t |
| 21 |
NAK |
53 |
5 |
85 |
U |
117 |
u |
| 22 |
SYN |
54 |
6 |
86 |
V |
118 |
v |
| 23 |
ETB |
55 |
7 |
87 |
W |
119 |
w |
| 24 |
CAN |
56 |
8 |
88 |
X |
120 |
x |
| 25 |
EM |
57 |
9 |
89 |
Y |
121 |
y |
| 26 |
SUB |
58 |
: |
90 |
Z |
122 |
z |
| 27 |
ESC |
59 |
; |
91 |
[ |
123 |
{ |
| 28 |
FS |
60 |
< |
92 |
\ |
124 |
| |
| 29 |
GS |
61 |
= |
93 |
] |
125 |
} |
| 30 |
RS |
62 |
> |
94 |
^ |
126 |
~ |
| 31 |
US |
63 |
? |
95 |
_ |
127 |
DEL |
| NUL 空字符 |
VT 垂直制表 |
SYN 同步 |
| SOH 标题开始 |
FF 走纸控制 |
ETB 信息组传送结束 |
| STX 正文开始 |
CR 回车 |
CAN 作废 |
| ETX 正文结束 |
SO 移位输出 |
EM 媒介结束 End of Medium |
| EOT 传输结束 |
SI 移位输入 |
SUB 换置 |
| ENQ 询问字符 |
DLE Data Link Escape |
ESC Escape |
| ACK 确认 |
DC1 设备控制1 |
FS 文件分隔符 |
| BEL 响铃 |
DC2 设备控制2 |
GS 组分隔符 |
| BS 退格 |
DC3 设备控制3 |
RS 记录分隔符 |
| HT 横向制表 |
DC4 设备控制4 |
US 单元分隔符 |
| LF 换行 |
NAK 否定 |
DEL 删除 |
参考资料:C Primer Plus, 5th Edtion By Stephen Prata
The C Programming Language 2e By K&R
本文版权归 蚂蚁的 C/C++ 标准编程 以及 作者 antigloss 共同所有,转载请注明原作者和出处。谢谢。