char 类型
char 是 C 语言中最小的整数类型,通常占用 1 字节(8 位)。它既可以存储字符(如 'A'、'\n'),也可以当作小整数参与运算(范围通常是 -128 到 127,或 0 到 255)。理解 char 的双重身份,是掌握 C 字符串和字符处理的基础。
基本用法
char 用于存储单个字符:
char grade = 'A';
char newline = '\n';
char digit = '7';
printf("Grade: %c\n", grade); /* 输出:Grade: A */
printf("ASCII of 'A': %d\n", grade); /* 输出:ASCII of 'A': 65 */
字符常量用单引号括起来,如 'A'、'+'、' '(空格)。注意区分单引号(字符)和双引号(字符串):'A' 是 char,"A" 是包含 'A' 和 '\0' 两个字符的字符串。
char 的本质是整数
在 C 语言中,char 本质上是一个整数类型,存储的是字符的编码值。最常用的编码是 ASCII(American Standard Code for Information Interchange),用 7 位表示 128 个字符:
char c = 'A';
printf("%d\n", c); /* 输出 65 */
char next = c + 1;
printf("%c\n", next); /* 输出 B */
/* 字符运算 */
char upper = 'M';
char lower = upper + ('a' - 'A'); /* 'M' + 32 = 'm' */
printf("%c -> %c\n", upper, lower); /* 输出:M -> m */
ASCII 码的核心分区:
| 范围 | 内容 |
|---|---|
| 0–31 | 控制字符(不可打印) |
| 32 | 空格 ' ' |
| 48–57 | 数字 '0'–'9' |
| 65–90 | 大写字母 'A'–'Z' |
| 97–122 | 小写字母 'a'–'z' |
| 127 | DEL 删除字符 |
常用码值速查:'0' = 48,'9' = 57,'A' = 65,'Z' = 90,'a' = 97,'z' = 122。数字字符转数值:'7' - '0' = 7。
signed char 与 unsigned char
C99 规定 char 的类型等价于 signed char 或 unsigned char,由编译器决定。这会影响字符的取值范围和比较行为:
char c = 200; /* 如果 char 有符号,200 溢出(实际为 -56) */
/* 如果 char 无符号,值为 200 */
if (c > 0)
printf("Positive\n"); /* 结果取决于 char 是否有符号! */
可以通过 <limits.h> 中的 CHAR_MIN 判断:
#include <limits.h>
if (CHAR_MIN < 0)
printf("char is signed\n");
else
printf("char is unsigned\n");
如果需要明确的语义,直接写 signed char 或 unsigned char:
signed char temperature; /* 可能为负 */
unsigned char pixel_value; /* 0-255,图像像素 */
转义字符
某些字符无法直接输入或显示,用反斜杠开头的转义序列表示:
| 转义序列 | 含义 | ASCII 码 |
|---|---|---|
\n | 换行 | 10 |
\t | 水平制表符 | 9 |
\r | 回车 | 13 |
\\ | 反斜杠 | 92 |
\' | 单引号 | 39 |
\" | 双引号 | 34 |
\0 | 空字符 | 0 |
\a | 警报(响铃) | 7 |
\b | 退格 | 8 |
\f | 换页 | 12 |
\v | 垂直制表符 | 11 |
printf("Line1\nLine2\n"); /* \n 换行 */
printf("Column1\tColumn2\n"); /* \t 制表 */
printf("He said \"Hello\"\n"); /* \" 双引号 */
还可以用八进制或十六进制表示任意字符:
char a = '\101'; /* 八进制 101 = 十进制 65 = 'A' */
char b = '\x41'; /* 十六进制 41 = 十进制 65 = 'A' */
字符分类函数
实际开发中,应优先使用 <ctype.h> 的函数处理字符,而非手动比较 ASCII 码:
#include <ctype.h>
char c = 'm';
if (isalpha(c)) printf("Letter\n"); /* 字母 */
if (isdigit(c)) printf("Digit\n"); /* 数字 */
if (islower(c)) printf("Lowercase\n"); /* 小写 */
if (isupper(c)) printf("Uppercase\n"); /* 大写 */
if (isspace(c)) printf("Whitespace\n"); /* 空白 */
char upper = toupper(c); /* 'm' -> 'M' */
char lower = tolower(c); /* 'M' -> 'm' */
<ctype.h> 的函数正确处理了 ASCII 之外的字符集(如扩展 ASCII 或 Unicode),手动比较 'a' <= c && c <= 'z' 在本地化环境下可能出错。
常见错误
混淆字符和字符串:
char c = "A"; /* 警告:用字符串初始化 char */
/* 实际存储的是指针的低字节 */
char *s = 'A'; /* 警告:用整数初始化指针 */
将数字与数字字符混淆:
char c = 7; /* 存储 ASCII 码 7(BEL 响铃控制字符) */
char d = '7'; /* 存储 ASCII 码 55 */
printf("%c\n", c); /* 可能无输出或响铃 */
printf("%c\n", d); /* 输出 7 */
有符号 char 的溢出:
char c = 150; /* 如果 char 有符号,150 超出范围 */
printf("%d\n", c); /* 可能输出 -106 */