C语言程序设计教程
上QQ阅读APP看书,第一时间看更新

2.5 字符型数据

2.5.1 字符型常量

字符常量是用一对单引号括起来的单个字符,如'A'、'a'、'X'、'?'、'$'都是字符常量。注意,单引号是定界符,不是字符常量的一部分,如果不用单引号括起来,如 a,编译器将认为a是一个变量或者是其他有名称的对象。

在计算机内存中,字符是按ASCII码值存储的。字符常量'a'对应的ASCII码值是97,'A'对应的ASCII码值是65,所以'a'和'A'是两个不同的字符常量。同样,'0'对应的ASCII码值是48,而0本身就是一个整型常量。'0'和0两者是不相同的。

除了以上形式的字符常量外,C语言中还包含一种特殊的表现形式即转义字符。其形式为反斜杠“\”后面跟一个数值或一个字符。如'\102'表示字符'B','\n'为换行。其中'\n'是一种“控制字符”,在屏幕上是不能显示的,在程序中也无法用一个一般形式的字符表示,只能采用特殊形式来表示。所以C语言规定用'\'开头的字符其后跟随的字符用另外的意思代替。常见的转义字符如表2-3所示。

表2-3 常见的转义字符

其中,“\ddd”的形式表示1~3位八进制数所代表的字符,如“\101”代表八进制数101 (十进制数65)的ASCII码所对应的字符为“A”;“\xhh”的形式表示1~2位十六进制数所代表的字符,如“\x42”代表十六进制数42(十进制数66)的ASCII码所对应的字符为“B”。

【例2.7】 转义字符的使用。

#include <stdio.h>

void main()

{

  printf("□ab□c\t□de\rf\tg\n"); // □ 表示一个空格

  printf("h\ti\b\bj□k");

}

程序运行后在显示屏上的输出结果如下所示。

f□□□□□□□gde

h□□□□□□j□k

程序分析如下。

(1)第一个printf函数先在第一行左端开始输出“□ab□c”。

(2)遇到“\t”,它的作用是“跳格”,即跳到下一个“制表位置”,在我们所用的系统中,一个“制表区”占8列。“下一制表位置”从第9列开始,故在第9~11列上输出“□de”。

(3)遇到“\r”,它代表“回车”(不换行),返回到本行最左端(第1列),输出字符“f ”。

(4)遇到“\t”,使当前输出位置移到第9列,输出“g”。

(5)遇到“\n”,作用是使当前位置移到下一行的开头。

(6)第二个printf函数先在第一列输出字符“h”,后面的“\t”使当前位置跳到第9列,输出字符“i”,此时已输出“h□□□□□□□i”。

(7)当前位置移到下一列(第10列)准备输出下一个字符。遇到两个“\b”,“\b”的作用是退一格,因此“\b\b”的作用是使当前位置回退到第8列,接着输出字符“j□k”,j后面的“□”将原有的字符“i”取而代之,因此屏幕上看不到“i”。

注意:为什么运行结果中开始输出的“□ab□c”没有了?

这是由于“\r”使当前位置回到本行的开头,由此输出的字符(包括空格和跳格所经过的位置)将取代原来屏幕上该位置上显示的字符,所以原有的字符“□ab□c□□□□”被新的字符“f□□□□□□□□g”代替,其后的“de”未被新字符代替。

实际上,屏幕上完全按程序要求输出了全部的字符,只是因为在输出前面的字符后,很快又输出后面的字符,在人们还未看清楚之前,新的已取代了旧的,所以误以为未输出应该输出的字符。若在打印机上输出,则结果如下所示。

f ab□c□□□gde

h□□□□□□jik

它不像显示屏那样会“抹掉”原字符,而是留下了痕迹,它能真正反映输出的过程和结果。

2.5.2 字符型变量

字符变量的类型关键字为char,占用一个字节的内存单元。字符变量用来存储字符常量,一个字符变量只能存储一个字符常量。在存储时,实际上是将该字符的ASCII码值(无符号整数)存储到内存单元中。例如,“x”的十进制ASCII码是120,“y”的十进制ASCII码是121。对字符变量a、b赋予“x”和“y”值。

char a,b;    // 定义两个字符变量a、b

a='x';      // 给字符变量赋值

b='y';

实际上是在a、b两个单元内存放120和121的二进制代码。

变量a在内存中的存放形式:

变量b在内存中的存放形式:

字符数据在内存中存储的是字符的ASCII码值,即一个无符号整数,其形式与整数的存储形式一样,所以C语言允许字符型数据与整型数据之间可以通用。

(1)一个字符型数据,既可以以字符形式输出,也可以以整数形式输出。以字符形式输出时,系统先将存储单元中的ASCII码转换成相应字符再输出;以整数形式输出时,直接将ASCII码作为整数输出。

【例2.8】 字符变量的字符形式输出和整数形式输出。

#include<stdio.h>

void main()

{

  char a,b;

  a='x';

  b='y';

  printf("%c,%c\n",a,b);     //以字符的形式输出

  printf("%d,%d\n",a,b);     //以整数的形式输出

}

注意:字符数据占一个字节,它只能存放0~255的整数,而char是有符号存放-128~127,超过127用负数存放。其中,%c是输出字符时使用的格式符,%d是输出整型数据时使用的格式符。

(2)允许对字符数据进行算术运算,此时就是对它们的ASCII码值进行算术运算。

【例2.9】 字符数据的算术运算。

#include <stdio.h>

void main()

{

  char ch1,ch2;

  ch1 = 'a'; ch2 = 'B';

  printf("ch1 = %c,ch2 = %c\n",ch1-32,ch2+32); // 字母的大小写转换

}

从【例 2.9】中可以看出,程序的作用是将小写字母 a 转换成大写字母 A,大写字母 B转换成小写字母a。“a”的ASCII码为97,而“A”的ASCII码为65,“B”的ASCII码为66,而“b”的ASCII码为98。从ASCII代码表中可以看到每一个小写字母的ASCII码比它相应的大写字母的ASCII码大32。

(3)字符型数据和整型数据可以相互赋值。

字符数据在内存中存储的是字符的ASCII码值,因此可以把字符型数据看成是整型量。C语言允许对整型变量赋以字符值,也允许对字符变量赋以整型值。

【例2.10】 字符型数据和整型数据相互赋值。

#include <stdio.h>

void main()

{

  int i;

  char c;

  i='a';       //将字符常量赋给整型变量

  c=97;        //将整型常量赋给字符变量

  printf("%c,%d\n",c,c);

  printf("%c,%d\n",i,i);

}

2.5.3 字符串常量

字符串常量是用一对英文双引号括起来的字符序列,如"abc""CHINA""yes""1234""How do you do"都是字符串常量。双引号不是字符串的一部分,只起定界的作用。

字符串和字符不同,它们之间主要有以下区别。

(1)字符由单引号括起来,字符串由双引号括起来。

(2)字符只能是单个字符,字符串则可以含一个或多个字符。

(3)可以把一个字符型数据赋予一个字符变量,但不能把一个字符串赋予一个字符变量。在C语言中没有相应的字符串变量,也就是说不存在这样的关键字,将一个变量声明为字符串。但是可以用一个字符数组来存放一个字符串,这将在数组一章内予以介绍。

(4)字符占一个字节的内存空间。字符串占的内存字节数等于字符串中的字符数加 1。增加的一个字节中存放字符“\0”(ASCII码为0),这是字符串结束的标志。

例如,字符串“C program”在内存中所占的字节为10个字节而非9个字节,如下所示。

同理可知,字符'a'和字符串"a"虽然都只有一个字符,但在内存中的情况是不同的。'a'在内存中占一个字节,"a"在内存中占两个字节,可分别表示如下:

注意:在写字符串时不必加“\0”,否则会画蛇添足。字符“\0”是系统自动加上的。

程序设计过程中,可以将多个字符串常量连接起来并进行输出,如【例2.11】所示。

【例2.11】 字符串常量被连接实例。

#include <stdio.h>

void main()

{

  printf("This is my first program in C\n");

}