字符类型
字符类型(Character type)变量,顾名思义是用来存储字符的变量。它也包括许多分类,不过我们只需要掌握其中一种就够了。这一种就是之前提到过的 char
型变量。
char
型变量是用于存储部分字符的变量。这部分字符被称作 ASCII 字符,它包括不可见字符和可见字符两部分,共 128 个。除了这 128 个字符之外的字符一般不能用 char
型变量来存储。其中:
- 不可见字符 33 个,包括换行、Tab(制表符)、退格、删除和响铃等控制字符。
- 可见字符 95 个,包括大小写字母、数字和常见符号等打印字符。
可见字符顾名思义是“可以看见”的字符。这些字符主要的作用是供读者阅读:比如 A
p
p
l
e
这五个字符共同组成了 Apple 这个单词,然后读者可以理解它的意思。不可见字符则是“不可以看见”的字符。有读者可能奇怪,不能看见的字符有什么用呢?其实它的作用主要是控制计算机的除了阅读外的一些其它功能:比如“换行字符”可以让控制台的光标移动到下一行,“响铃字符”可以让计算机发出一个声音等等。
可见字符可以用单引号引起的方式表示出来。比如
char at{'@'};
定义了一个名为 at
的字符型变量,它的初始化值是 '@'
,也就是目前存储了 @
这个字符。
存储细节
C++标准规定 char
型的大小为 1 字节。这就是为什么有的时候 char
就是字节类型的同义词。
常识告诉我们,计算机中只能存储二进制数,不能直接存储一个字符。所以计算机采用了 ASCII 码表来实现字符到数的对应。比如:
' '
(空格)对应 20'0'
(字符 0)对应 48'1'
(字符 1)对应 49- ……
'@'
对应 64'A'
对应 65'B'
对应 66- ……
'Z'
对应 90'a'
对应 97'b'
对应 98- ……
等等。有时我们称字符所对应的数为这个字符的ASCII码。完整的ASCII码表可以参见书后附录,我们不需要特别记忆它。
我们已经知道了如何将一些可见字符赋值给字符类型,那么如何将不可见字符——比如换行符赋给字符类型呢?又如何使用单引号 '
和双引号 "
却不引起歧义呢?这时需要使用转义字符这个概念。转义字符(Escaped character)是以反斜杠 '\'
开头的字符。反斜杠及其后面的字符将作为一个整体代表一个新的含义的字符。比如,我们使用 '\n'
表示换行符,使用 '\t'
表示制表符。可能的转义字符在下表列出:
转义字符 | 描述 | 表示 |
---|---|---|
\' | 单引号 | ASCII 编码中为字节 0x27 |
\" | 双引号 | ASCII 编码中为字节 0x22 |
\? | 问号 | ASCII 编码中为字节 0x3f |
\\ | 反斜杠 | ASCII 编码中为字节 0x5c |
\a | 响铃 | ASCII 编码中为字节 0x07 |
\b | 退格 | ASCII 编码中为字节 0x08 |
\f | 换页 | ASCII 编码中为字节 0x0c |
\n | 换行 | ASCII 编码中为字节 0x0a |
\r | 回车 | ASCII 编码中为字节 0x0d |
\t | 水平制表 | ASCII 编码中为字节 0x09 |
\v | 垂直制表 | ASCII 编码中为字节 0x0b |
\nnn | 任意八进制值 | 字节 nnn |
\xnn | 任意十六进制值 | 字节 nn |
同样地,转义字符也可以作为“一句话”的一部分出现在双引号内。下面是一个使用转义字符的例子:
它的编译运行结果为(并可能响铃一次):
This is the first line!
\
"'"
响铃与否取决于你使用的终端。如果直接在终端运行的话,Windows 10 会发出“噔咚咚”的响铃;macOS 可能会发出“嘟”的一声。
你可能已经注意到了,字符型和布尔型都属于整数类型的范畴。因此它们都可以像整数那样进行计算如加法、减法等:比如 'A' + 1
的结果就是 'B'
。下面这个例子简单演示了字符类型的运算:
它的运算结果如下,你可以对照 ASCII 码表进行验证:
@ 90
26 m
实际上,
char
类型也区分signed
与unsigned
。但是你可以发现它们的取值范围分别是 -128 ~ 127 和 0 256;其中都覆盖了 ASCII 码表的取值范围(0 ~ 127)。因此在存储 ASCII 字符时,char
的有无符号性是没有影响的。
总结
至此我们已经将 C++ 的最基础的类型——算术类型讲解完毕了。下面这张表大致地总结了它们:
类型说明符 | 含义 | 一般的字节数 | 一般的取值范围 | |
---|---|---|---|---|
signed | unsigned | |||
bool | 布尔类型 | 1 | true 或 false | |
char | 字符类型 | 1 | ASCII 字符 | |
short | 短整型 | 2 | ~ | ~ |
int | 整型 | 4 | ~ | ~ |
long ※ | 长整型 | 4 | ~ | ~ |
long long | 扩展长整型 | 8 | ~ | ~ |
float | 单精度浮点型 | 4 | 6~7 位有效数字 | |
double | 双精度浮点型 | 8 | 15~16 位有效数字 | |
long double | 扩展精度浮点型 | 8 | 不少于 15 位有效数字 |
※ 在 64 位的 UNIX 或类 UNIX 系统下, long
占用 8 字节,表示范围与 long long
相同。
练习
- 仿照上一章的“猜数游戏”,编写一个“猜字母”的游戏:程序指定一个大写字母,允许用户通过多次输入来猜测是哪一个字母,直至猜对为止。猜错的提示与“猜数游戏”相同,输出提示是猜“大”了还是“小”了。(提示:
char
型变量仍然可以通过大于、小于号进行比较。)
练习参考答案
#include <iostream>
using namespace std;
int main() {
char ans{'G'}; // 答案
char x{'A'}; // 这里不写初始化器也没有问题。
cin >> x;
while (x != ans) {
if (x > ans) {
cout << "That's bigger than the answer. Try again?" << endl;
}
if (x < ans) {
cout << "That's smaller than the answer. Try again?" << endl;
}
cin >> x;
}
cout << "Bingo! You got the answer!" << endl;
}