2. 字符
2.1 数据类型char
在C语言中,单个字符用数据类型char来表示,它是预定义的数据类型中的一种。
类型char由一个合法值的值域和一组操作这些值的运算组成。
因为char是标量类型,因此字符可用的运算集合与整数是一样的。
2.2 ASCII代码
单个字符在机器内部的表示方法和其他标量类型一样。
基本思想是,为每个字符赋一个编号,通过把这些字符写在一个表中,然后对它们计数来实现编号过程。
用于表示特定字符的代码,称为它的字符代码(character code)。
例如,可以用整数1代表字母A。
尽管设计一台用数字1表示字母A的计算机在技术上是可行的,但这样做确实是错误的。
为了使不同计算机之间的通信成为可能,计算机必须能以某种公共的语言“互相交谈”。
这种公共语言的基本特性在于,计算机用同样的代码表示字符。
采用了统一的字符表示标准,称为ASCII(发音为“as-key”) 字符编码系统,表示信息交换的美国标准代码(American Standard Code for Information Inter-change) 。
具体如下表所示:
![](https://i-blog.csdnimg.cn/blog_migrate/42b0c2634c7b8e4db889c82840a30f6c.png)
计算表中任何字符的ASCII值,只要将该项行和列相关的数字相加即可。
例如,字母A的ASCII值是60+5,即65。
当用户键入字母A时,键盘中的硬件自动将此字符翻译成ASCII代码65,然后把它发送给计算机。
同样,当计算机把ASCII代码65发送到屏幕时,屏幕上会出现字母A。
2.3 字符常量
当在一个C语言程序中用到某一特定字符时,标准的方法是指定一个字符常量(character constant)。即,将所需的字符括在一对单引号中。
例如,要指出字母A的ASCII值,所需要做的只是写’A’。
C编译器知道这个符号指的是用字母A的ASCII值,即65。
2.4 ASCII代码方案的重要特性
两个ASCII表的结构特性:
(1) 表示数字0~9的字符的代码是连续的。
数字’1’的代码是比’0’的代码大1的整数。
如果给’0’的代码加9,就是字符’9’的代码。
(2) 字母按字母顺序分成两段:
一段是大写字母
(
A
−
Z
)
(A-Z)
(A−Z),另一段是小写字母
(
a
−
z
)
(a-z)
(a−z)。
在每一段中, ASCII值是连续的。
2.5 特殊字符
在程序中,特殊字符(special character)是用反斜杠后跟一个字母或数值表示的。
反斜杠和它后面的字符的组合被称为转义序列(escape sequence)。
预定义的转义序列:
![](https://i-blog.csdnimg.cn/blog_migrate/8c493aa76c6dae65c0c207c17aff49b5.png)
当编译器看见反斜杠字符时,它把该字符看成是转义序列的第一个字符。
2.6 字符运算
在C语言中, 字符值能像整数一样计算,不需要特别转换。结果是根据其内部ASCII代码定义的。
例如,字符’A’在计算机内部用ASCII代码65表示,在运算时被当作整数65处理。
当对字符进行运算时,仅有很少的算术运算是有用的。有意义的运算通常包括:
(1) 给一个字符加上一个整数
如果c是一个字符,n是一个整数,表达式c+n表示代码序列中c后面的第n个字符。
如果n在1~26之间,那么’A’+n-1表示字母表中第n个字母的字符代码。
(2) 从一个字符中减去一个整数
表达式c-n表示代码序列中c前面的第n个字符。
例如,表达式’Z’-2的结果是’X’的字符代码。
(3) 从一个字符中减去另一个字符
如果c1和c2都是字符,那么表达式c1-c2表示两个字符在代码序列中的距离。
例如,‘a’-‘A’是32。更重要的是,小写字母和与之对应的大写字母之间的距离是固定的,因此’z’-'Z’也是32。
(4) 比较两个字符
经常用来确定字母的次序。
例如,如果在ASCII表中,c1在c2前面,那么表达式c1<c2是TRUE。
2.7 ctype.h接口
检查一个字符是否为数字或字母的操作很常见,C语言具有专用库。
该库的接口是ctype.h
,它导出一些确定字符类型的函数。
与任何其他接口一样, 可以通过包含行
#include<ctype.h>
来获得这些函数的访问权。
ctype.h
接口声明了一些确定字符类型的谓词函数。一些重要的函数如下:
islower(ch) - 如果字符ch是小写字母,则返回TRUE。
isupper(ch) - 如果ch是大写字母,则返回TRUE。
isalpha(ch) - 如果ch是字母(不管大写还是小写),则返回TRUE。
isdigit(ch) - 如果ch是数字,则返回TRUE。
isalnum(ch) - 如果ch是字母数字(alphanumeric),即或者是字母或者是数字,则返回TRUE。
ispunct(ch) - 如果ch是标点符号, 则返回TRUE。
isspace(ch) - 如果ch是下列字符之一,则返回TRUE。这些字符是’’(空格字符)、’\t’、’\n’、’\f’或’\v’,所有这些字符在屏幕上都显示为空格。
tolower(ch) - 如果ch是大写字母,返回它对应的小写字母;否则,返回ch本身。
toupper(ch) - 如果ch是小写字母,返回它对应的大写字母;否则,返回ch本身。
tolower
函数的代码实现:
#include <stdio.h>
/* Convert upper case letter into lower case letter.*/
/* Function Prototype */
char tolower(char ch);
/* Main Program */
main() {
char ch;
printf("Input a letter: ");
scanf("%c", &ch);
printf("The lower case letter is: %c\n", tolower(ch));
}
/* Function */
char tolower(char ch) {
if (ch >= 'A' && ch <= 'Z') {
return (ch + ('a' - 'A'));
}
else
{
return (ch);
}
}
尽管在ctype.h中定义的函数都很容易实现,但使用库函数而不是自己编写的函数是良好的程序设计习惯。
存在三个主要理由:
(1) 因为库函数是标准的,其他程序员读你编写的程序比较容易。
(2) 库函数比你自己写的函数更能保证正确性。
(3) 函数的库实现通常比你自己写的函数效率更高。
2.8 涉及字符的控制语句
因为char是标量类型,可以把它用在出现整数的所有语句中。
例如,如果ch声明为char类型,可以用下列for语句执行26次循环,按字母顺序对每个大写字母执行一次:
for (ch='A'; ch<='Z'; ch++)
此外,也可以将字符用在switch语句的控制表达式中。
例如,如果参数为元音的话,下面的谓词函数返回true:
bool isvowel(char ch) {
switch (tolower(ch)) {
case 'a': case 'e': case 'i': case 'o': case 'u':
return true;
default:
return false;
}
}
参考
《C语言的科学和艺术》 —— 第9章 字符串和字符