任务描述
用来存放字符量的数组称为字符数组。C语言没有专门的字符串变量,字符串的存储必须通过字符数组来实现。一维字符数组用于存储1 个字符串(每个元素存放1 个字符),二维字符数组用于同时存储多个字符串(每一行存储1 个字符串)。
知识学习
字符数组是存放字符型数据的数组,其中每个数组元素的值都是一个字符。字符数组也是数组,其定义、初始化、引用方式与之前学过的一维数组和二维数组基本一样,唯一的区别是字符数组的数组元素的类型为字符型。
(1)字符数组的定义
一维字符数组的一般格式为:
char 数组名[常量表达式];
例如:
char a[10];
上述定义的结果,在内存中分配10 个字节的连续存储单元,可以存放10 个字符或者一个长度不超过9 的字符串。
二维字符数组的一般格式为:
char 数组名[常量表达式1][常量表达式2];
例如:
char a[3][12];
上述定义的结果,在内存中分配3 ×12 个字节的连续存储单元,可以存放3 ×12 个字符或者3 个长度不超过11 的字符串。
(2)字符数组的引用
同普通数组元素的引用形式一样,可以引用字符数组中的任一个元素,得到一个字符。
(3)字符数组的初始化
对字符数组初始化有下面两种情况。
例如:
char a[10] = {'C',' ','p','r','o','g','r','a','m'};
赋值后各元素的值为:
a[0]的值为'C'
a[1]的值为' '
a[2]的值为'p'
a[3]的值为'r'
a[4]的值为'o'
a[5]的值为'g'
a[6]的值为'r'
a[7]的值为'a'
a[8]的值为'm'
其中a[9]未赋值,由系统自动赋予0 值。
当对全体元素赋初值时也可以省去长度说明。
例如:
char a[] ={ 'C', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'};
这时a 数组的长度自动定为9。
说明:
①初值个数可以少于数组长度,多余元素自动为'\0'(C语言中,\0 的ACSII 码是0)。
例如:
char a[6] ={ 'c','h','i','n','a'};
则char a[5] = '\0',即a[5] = 0
②对于一维字符数组指定初值时,若未指定数组长度,则长度等于初值个数。例如:
char a[] ={'I',' ','a','m',' ','h','a','p','p','y'};
等价于:
char a[10] ={'I',' ','a','m',' ','h','a','p','p','y'};
③对于二维数组可以不指定第一维长度。
char a[][10] ={"hello ","world"};
系统默认第一维长度为2。
例4.8 字符串的输出。
程序运行结果如图4.10所示。
图4.10 例4.8 程序运行结果
(4)字符串和和字符串结束标志
在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。前面介绍字符串常量时,已说明字符串总是以'\0'作为串的结束符。因此当把一个字符串存入一个数组时,也把结束符'\0'存入数组,并以此作为该字符串是否结束的标志。有了'\0'标志后,就不必再用字符数组的长度来判断字符串的长度了。
C语言允许用字符串的方式对数组作初始化赋值。
例如:
char a[] ={'C', ' ','p','r','o','g','r','a','m'};
可写为:
char a[] ={"C program"};
或去掉{}写为:
char a[] = "C program";
用字符串方式赋值比用字符逐个赋值要多占一个字节,用于存放字符串结束标志'\0'。上面的数组a 在内存中的实际存放情况为:
'\0'是由C 编译系统自动加上的,由于采用了'\0'标志,所以在用字符串赋初值时一般无须指定数组的长度,而由系统自行处理。
(5)字符数组的输入输出
可以利用字符数组对单个字符或字符串进行输入输出操作。
1)单个字符的输入输出
a.用格式符“%c”输入或输出单个字符。例如:
第一个for 循环语句,从键盘输入字符赋给a[0]、a[1]、a[2]、a[3]、a[4]……, 第2 个for循环语句则将字符数组元素的值逐个输出。
b.字符输入函数getchar()
getchar()函数作用是从输入设备(如键盘)读取一个字符。函数getchar()没有参数,其一般形式为:
int getchar(void );
其执行结果是从输入设备得到一个字符。
可见,getchar()函数同带格式符%c 的scanf()函数都可以接收一个字符,并且可以将得到的字符赋给一个字符型变量或者整型变量。但是不是所有场合二者都可以互相替换。它们的不同之处包括:getchar()一次只能接收一个字符,getchar()可以接收回车字符;而scanf()将回车作为数据的间隔符或结束符;getchar()接收的字符可以不赋给任何变量。
c.字符输出函数putchar()
putchar()函数作用是将一个字符输出到输出设备(如显示器)。它的一般形式为
int putchar(int c);
函数putchar()的可以输出字符型变量、整型变量、字符型常量以及控制字符和转义字符。
2)字符串的输入输出
用格式符“%s”输入或输出字符串。
由于C语言没有专门的变量存放字符串,字符串只能存放在一个字符数组中,数组名表示字符串的首地址,即第一个字符的地址,因此在输入或输出字符串时可以直接使用数组名。
例如:
char a[10];
scanf("%s",a);∥由键盘输入字符串
printf("%s",a);
使用说明如下:
a.按“%s”格式符输出时,即使数组长度大于字符串长度,也是遇'\0'结束,且输出字符中不包含'\0'。若数组中包含多个'\0',则遇到第一个'\0'时结束。例如:
char a[10] ={"China"};
printf("%s",c);∥只输出5 个字符
b.按“%s”格式符输出字符串时,printf 函数的输出项是字符数组名,而不是元素名。
(www.xing528.com)
c.按“%s”格式符输入时,遇“回车”键结束,但获得的字符中不包含回车键本身,而是在字符串末尾添'\0'。因此,定义的字符数组必须有足够的长度,以容纳所输入的字符,例如,输入5 个字符,定义字符数组的长度至少是6。
d.一个scanf 函数输入多个字符串,输入时以“空格”键或者“回车”键作为字符串间的分隔。
例如:
char strl[5],str2[5],str3[5];
scanf("%s%s%s",strl,str2,str3);
输入数据:
How are you?
str1、str2、str3 获得的数据如图4.11所示。
图4.11 str1、str2、str3 的数据存储情况
e.C语言中,数组名代表该数组的起始地址,因此,scanf 函数中不需要地址运算符。
例如:
char str[13];
scanf ("%s",str);
例4.9 字符串的输入与输出,运行结果如图4.12所示。
图4.12 例4.9 程序运行结果
(6)字符串处理函数
C语言提供了丰富的字符串处理函数,大致可分为字符串的输入、输岀、合并、修改、比较、转换、复制、搜索几类。使用这些函数可大大减轻编程的负担。用于输入输出(包括:scanf()和printf()、gets()和puts()、getchar()和putchar())的字符串函数,在使用前应包含头文件“stdio.h”,使用其他字符串函数则应包含头文件“string.h”。
1)字符串输出函数puts
格式:puts(字符数组名)
功能:把字符数组中的字符串输出到显示器,即在屏幕上显示该字符串。输出时自动将字符串结束标志'\0'转换为回车换行符。
注意:标准输出函数printf()与格式控制符%s 配合,也能实现字符串的输出操作,与puts()不同的是,printf()在输出字符串后光标不换行,而puts()输出字符串后光标回车换行。
例4.10 使用puts()函数实现字符串输出,运行结果如图4.13所示。
图4.13 例4.10 程序运行结果
2)字符串输入函数gets
格式:gets(字符数组名)
功能:从标准输入设备键盘上输入一个字符串,以回车符结束,并将字符串存放到指定的字符数组或存储区域中。
注意:标准输入函数scanf()与格式控制符%s 配合,也能实现字符串的输入操作,与gets()不同的是,scanf()在输入字符串时遇空格即结束,也就是说,scanf()只能输入不带空格的字符串。
例4.11 使用gets()函数实现字符串输入。
图4.14 例4.11 程序运行结果
3)字符串连接函数strcat
格式:strcat(字符数组名1,字符数组名2)
功能:把字符数组2 中的字符串连接到字符数组1 中字符串的后面,并删去字符串1 后的串标志'\0'。本函数返回值是字符数组1 的首地址。
注意:字符数组1 所对应的存储空间要能容得下连接后的字符串。
例4.12 字符串的连接。
图4.15 例4.12 程序运行结果
4)字符串复制函数strcpy
格式:strcpy(字符数组名1,字符数组名2);
功能:把字符数组2 中的字符串复制到字符数组1 中,串结束标志'\0'也一同复制。
注意:字符数组1 所对应的存储空间不能小于字符数组2 所对应的存储空间,不能用赋值语句将一个字符串常量或字符数组直接赋给另一个字符数组。
例4.13 字符串的复制。
图4.16 例4.13 程序运行结果
5)字符串比较函数strcmp
格式:strcmp(字符数组名1,字符数组名2);
功能:按照ASCII 码顺序比较两个数组中的字符串,并由函数返回值返回比较结果。
字符串1 =字符串2,返回值=0;
字符串1 >字符串2,返回值=1;
字符串1 <字符串2,返回值= -1。
比较规则:将两个字符串自左至右逐个字符按ASCII 值大小比较,直到出现不同的字符或遇'\0'为止。若全部字符相同,则认为两个字符串相等,返回0 值;否则,计算第一对不同字符的ASCII 值之差,若为正整数,则字符串1 大于字符串2,返回值为1;若为负整数,则字符串1小于字符串2,返回值为-1。
注意:字符串strl 和str2 的比较,不能用形如字符串1 >字符串2 的条件表达式来实现。
例4.14 字符串的比较。
6)测字符串长度函数strlen
格式:strlen(字符数组名);
功能:测字符串的实际长度(不含字符串结束标志'\0')并作为函数返回值。
例4.15 求字符串长度。
图4.17 例4.14 程序运行结果
图4.18 例4.15 程序运行结果
(7)字符数组的程序举例
例4.16 编写一个密码输入程序,要求判断输入的字符串是否和预先设置的密码相同,相同输出“密码输入正确”,否则输出“密码不正确”。
图4.19 例4.16 程序运行结果
程序分析:
定义两个字符数组,数组password 存放事先设置好的密码,数组str 存放从键盘输入的密码,把str 字符串和password 字符串做比较,如果相等则密码正确,不相等则密码输入错误。
例4.17 输入5 个国家的名称按字母顺序排列输出。
图4.20 例4.17 程序运行结果
程序分析:
第一个for 语句中,用gets 函数输入5 个国家名字字符串。C语言允许把一个二维数组按多个一维数组处理,本程序cs[5][20]为二维字符数组,可分为5 个一维数组cs[0]、cs[1]、cs[2]、cs[3]、cs[4]。因此在gets 函数中使用cs[i]是合法的。在第二个for 语句中又嵌套了一个for 语句组成双重循环,这个双重循环完成按字母顺序排序的工作。在外层循环中把字符数组cs[i]中的国名字符串复制到数组st 中,并把下标i 赋予p;进入内层循环后,把st 与cs[i]以后的各字符串做比较,若有比st 小者则把该字符串复制到st 中,并把其下标赋予p。内循环完成后如p 不等于i 说明有比cs[i]更小的字符串出现,因此交换cs[i]和st 的内容。至此已确定了数组cs 的第i 号元素的排序值,然后输出该字符串,在外循环全部完成之后即完成全部排序和输出。
任务总结
字符数组是用来存放多个字符使用。如果存放的是一串字符则使用一维字符数组即可,如验证码等;如果存放的是多串字符则使用二维数组,如多位同学的姓名。
字符数组中如果存放的是字符串,系统会在字符串末尾处自动加一个转义字符'\0',表示字符串的结束标志。需要说明的是'\0'并不是字符串的组成部分,在计算字符串长度时不算'\0'。'\0'只是起到标识字符串结束的作用。
字符串的输入输出:在输入时使用scanf("%s",……);,如果遇见了空格、Tab 键、回车键则都是表示一个字符串输入结束。在输入时使用gets(……);,如果遇见的回车键则表示一个字符串输入结束,而空格和Tab 键对gets 不起作用,会作为有效字符存入对应的数组中。在输出时使用printf ("%s",……);,则输出字符串后不会换行。在输出时使用puts(……);,则输出字符串后会输出换行效果,系统会将'\0'转换为'\n' 再输出。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。