




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章字符串8.1字符串
8.2函数间字符串的传递
习题
8.1字符串
8.1.1字符串常量
1.定义
字符串常量是由一对双引号括起来的字符序列。例如,"China","Howareyou","$abc","123569","string" 等都是合法的字符串常量。
2.说明
(1)双引号仅仅起到字符串常量的边界符作用,并不是字符串常量的一部分。
(2)注意区分字符串常量和字符常量的区别。例如,"c" 和 'c' 是根本不同的数据,前者是字符串常量,后者是字符常量。它们之间主要有以下区别:
①字符常量由单引号括起来,字符串常量由双引号括起来;
②字符常量只能是单个字符,字符串常量则可以含一个或多个字符;
③可以把一个字符常量赋予一个字符变量,但不能把一个字符串常量赋予一个字符变量;
④字符常量占一个字节的内存空间。8.1.2字符串的存储
C语言规定:在每一个字符串的结尾加一个“字符串结束标志”,以便系统据此判断字符串是否结束。同时C语言也规定:以字符 '\0' 作为字符串的结束标志。字符 '\0' 是一个ASCII码为0的字符。从ASCII代码表中可以看到,ASCII码为0的字符是“空操作字符”,它不引起任何控制动作,也不是一个可显示的字符,即它什么也不做。用它作为字符串结束标志不会产生附加的操作或增加有效字符,它只是一个供辨别的标志。
因此,字符串常量在内存中所占的字节数等于字符串中有效字符所占的字节数(即有效字符的个数)再加1个字节。增加的一个字节存放的是字符串结束的标志'\0'。例如:字符串 "Welcome" 在内存中所占的字节为:
注意区分字符串常量和字符常量的区别。例如 "s" 和 's' ,字符串常量 "s" 和字符常量 's'虽然都只有一个字符,但在内存中的情况是不同的。字符串 "s" 在内存中占2个字节,可表示为:
字符 's' 在内存中占一个字节,可表示为:
注意:在写字符串时不必加 '\0' ,'\0' 字符是系统自动加上的。8.1.3字符串的表示
1.字符数组
C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。C语言允许用字符串的方式对字符数组作初始化,即可以用字符数组存放一个字符串。
例如:
charc[]={'W','e','l','c','o','m','e'};
可写为:
charc[]={"Welcome"};
也可以省略花括号,直接写为:
charc[]="Welcome";注意:用字符串方式赋值比用字符逐个赋值要多占一个字节,多占的字节用于存放字符串结束标志 '\0'。因此,以下两个字符数组的初始化等价,其字符数组的长度都是8。
charc[]="Welcome";
charc[]={'W','e','l','c','o','m','e','\0'};
字符数组完整的应用程序举例如下:
/*源程序8-1*/
#include"stdio.h"
main()
{
charstring[]="WelcometoChina!";
printf("%s\n",string);
}
程序运行结果如下:
2.字符指针
也可以不定义字符数组,而定义一个字符指针,用字符指针指向字符串中第一个字符的地址。
/*源程序8-2*/
#include"stdio.h"
main()
{
char*string="WelcometoChina!";
printf("%s\n",string);
}
程序运行结果如下:
3.字符数组和字符指针变量的区别
(1)字符数组有若干个元素,每个元素中存放一个字符;而字符指针变量中存放的是字符串中第一个字符的地址。
(2)赋值方式的不同。
例如:字符指针的赋值语句:
char*string="Welcome";
它等价于:
char*string;
string="Welcome";
因为可以将字符串的首地址存放在指针变量中。而字符数组的赋值语句:
charstring[]="Welcome";
它不等价于:
charstring[];
string[]="Welcome";
因为string表示字符数组的首地址,是常量,不能在赋值号的左端进行修改,不能将字符串的首地址赋值给数组名。
(3)字符数组在编译时为其分配存储单元,有确定的地址;字符指针分配的内存单元只能存放一个字符变量的地址,若没有赋值,则没有确定的指向。
charstring[20];
scanf("%s",string);
以上语句是正确的。
char*p;
scanf("%s",p);
以上语句是错误的,因为字符指针没有指向任何存储空间,不能输入字符串。应改成:
charstring[20],*p;
p=string;
scanf("%s",p);
(4)指针变量的值可以改变,是变量;数组名是常量,它的值是不能改变的。
/*源程序8-3*/
#include"stdio.h"
main()
{
char*string="WelcometoChina!";
string=string+11;
printf("%s\n",string);
}程序运行结果如下:将程序改为
/*源程序8-4*/
#include"stdio.h"
main()
{
charstring[]="WelcometoChina!";
string=string+11;
printf("%s\n",string);
}
以上程序是错误的,原因在于数组名是常量,它的值是不能改变的。 8.2函数间字符串的传递
8.2.1单个字符串的传递
函数的参数不仅可以是整型、实型、字符型等数据,还可以是数组和指针类型。将字符串从一个函数传递到另一个函数,可以用字符数组名或指向字符串的指针作参数,实际上传递的是字符串的起始地址。在被调用的函数中如果改变了字符串的内容,则在主调函数中可以得到改变了的字符串。/*源程序8-5*/
#include"stdio.h"
main()
{
voidcopy_str(char*from,char*to);//函数的声明
chara[50]="Iamateacher.";
char*b="WelcometoChina!";
printf("a=%s\nb=%s\n",a,b);
copy_str(b,a);
printf("a=%s\nb=%s\n",a,b);}
voidcopy_str(char*from,char*to)
{
inti=0;
while(from[i]!='\0')
{
*(to+i)=from[i];
i++;
}
to[i]='\0';
}程序运行结果如下:8.2.2多个字符串的传递
在一个数组中,如果每个元素都是指针类型数据,则称该数组为指针数组。也就是说,指针数组中的每一个元素都相当于一个指针变量。指针数组的一般定义形式为:
类型名*数组名[数组长度];
例如:
char*str[3];
表示str是一个指针数组,该数组有3个元素,每个元素值都是一个指针变量,指向字符型变量。应特别注意指针数组和指向一维数组的指针变量的区别。例如:
char(*str)[3];
表示str是一个指向一维数组的指针变量,该一维数组的长度为3,数组的元素类型为字符型。
指针数组的一个典型的应用是用它来指向若干个字符串,使字符串的处理更加方便灵活。同时也可以将指针数组作为函数的参数,此时传递的将是此指针数组的起始地址。可以通过此种方法来处理多个字符串。/*源程序8-6*/
#include"stdio.h"
main()
{
voidprint(char*string[],intn);//函数的声明
char*str[3];
str[0]="WelcometoChina!";
str[1]="Followme";
str[2]="Iamateacher.";
print(str,3);
}
voidprint(char*string[],intn)
{
inti;
for(i=0;i<n;i++)
printf("%s\n",string[i]);
}
程序运行结果如下:8.2.3main函数的参数
指针数组的一个重要应用是作为main函数的形参。实际上,main函数可以有参数,这个参数可以认为是main函数的形式参数。C语言规定main函数的参数只能有两个,习惯上将这两个参数写为argc和argv。因此,带参数的main函数头可写为:
main(intargc,char*argv[])C语言规定:main函数的第一个形参argc必须是整型变量,main函数的第二个形参argv必须是指向字符串的指针数组。由于main函数不能被其他函数调用,因此不可能在程序内部取得实际值。那么,在什么时候、在何处把实参值赋予main函数的形参呢?实际上,main函数的参数值是从操作系统命令行中获得的。也就是在一个命令行中包括命令名和需要传给main函数的参数。命令行的一般形式为:
可执行文件名参数1参数2…参数n其中可执行文件名(即命令名)和各参数之间用空格分隔。应该特别注意的是main函数的两个形参和命令行中的参数在位置上的对应关系。因为main的形参只有两个,而命令行中的参数个数原则上未加限制。第一个形参argc表示了命令行中参数的个数(注意:可执行文件名本身也算一个参数),argc的值是在输入命令行时由系统按实际参数的个数自动赋予的;第二个形参argv是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。指针数组的长度即为参数个数。数组元素初值由系统自动赋予。例如有如下命令行:
cmdnameBASICfoxproFORTRANC
在此命令行中,cmdname为可执行文件名,BASIC、foxpro、FORTRAN和C为参数。则对应于此命令行的main函数的形参argc为5,形参argv的对应关系如图8-1所示。图8-1argv的对应关系/*源程序8-7*/
#include"stdio.h"
main(intargc,char*argv[])
{
inti;
for(i=0;i<argc;i++)
printf("%s\n",argv[i]);
}假设此程序保存在D:\,文件名为m.c;经过编译、连接之后将会得到可执行文件m.exe。则该程序的执行过程和运行结果如下:8.2.4字符串处理函数
C语言提供了大量的字符串处理函数,使用这些字符串处理函数可简化编程。在使用输入/输出的字符串函数时,应包含头文件 "stdio.h";在使用其他字符串处理函数时,应包含头文件 "string.h"。以下介绍几种最常用的字符串函数。
1.字符串输出函数puts
格式:puts(字符数组)
功能:将字符数组中的字符串(以 '\0' 作为结束标志)输出到终端,即在屏幕上显示该字符串。/*源程序8-8*/
#include"stdio.h"
main()
{
charstr[]="BASIC\ndBASE\nC";
puts(str);
}程序运行结果如下:
从程序中可以看出,puts函数中可以使用转义字符,因此输出结果成为两行。puts函数完全可以由printf函数取代。当需要按一定格式输出时,通常使用printf函数。
2.字符串输入函数gets
格式:gets(字符数组)
功能:从标准输入设备(键盘)上输入一个字符串到字符数组,并得到一个函数值,函数值为该字符数组的首地址。/*源程序8-9*/
#include"stdio.h"
main()
{
charst[20];
printf("inputstring:\n");
gets(st);
puts(st);
}程序运行结果如下:
注意:当输入的字符串中含有空格时,输出仍为全部字符串。gets函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束的标志。这与scanf函数是不同的。
3.字符串连接函数strcat
格式:strcat(字符数组1,字符数组2)
功能:将字符数组2中的字符串连接到字符数组1中字符串的后面,并删去字符串1原有的串结束标志 '\0'。本函数的返回值是字符数组1的首地址。/*源程序8-10*/
#include"stdio.h"
#include"string.h"
main()
{
charst1[40]="Yournameis";
charst2[20];
printf("inputyourname:\n");
gets(st2);
strcat(st1,st2);
puts(st1);
}程序运行结果如下:
本程序把初始化赋值的字符数组与动态赋值的字符串连接起来。需要特别注意的是,字符数组1应定义有足够的长度,否则不能全部装入被连接的字符串。
4.字符串拷贝函数strcpy
格式:strcpy(字符数组1,字符串2)
功能:把字符串2中的字符拷贝到字符数组1中,字符串2中的结束标志 '\0' 也一同拷贝到字符数组1中。字符串2也可以是一个字符串常量,这时相当于把一个字符串赋予一个字符数组。/*源程序8-11*/
#include"stdio.h"
#include"string.h"
main()
{
charst1[30],st2[]="Cpromgram";
strcpy(st1,st2);
puts(st1);
}程序运行结果如下:
本函数要求字符数组1应有足够的长度,否则不能全部装入所拷贝的字符串。
5.字符串比较函数strcmp
格式:strcmp(字符串1,字符串2)
功能:对于这两个字符串,从左至右逐个字符进行比较,字符的比较按照所对应ASCII码的大小进行,直到出现不同的字符或遇到'\0'为止。本函数的返回值是最终比较的结果,即:
(1)若字符串1等于字符串2,则返回值为0;
(2)若字符串1大于字符串2,则返回值为正整数;
(3)若字符串1小于字符串2,则返回值为负整数。
本函数也可用于比较两个字符串常量,或比较数组和字符串常量。/*源程序8-12*/
#include"stdio.h"
#include"string.h"
main()
{
intk;
charst1[20],st2[]="WelcometoChina!";
printf("inputastring:\n");
gets(st1);k=strcmp(st1,st2);
if(k==0)
printf("st1=st2\n");
if(k>0)
printf("st1>st2\n");
if(k<0)
printf("st1<st2\n");
}程序运行结果如下:
本程序把输入的字符串和数组st2中的串比较,比较结果返回到k中,根据k的值输出比较的结果。当输入字符串为 "Welcometoxi’an" 时,由ASCII码可知“Welcometoxi’an”大于“WelcometoChina!”,故k>0,输出结果为“st1>st2”。
6.测字符串长度函数strlen
格式:strlen(字符数组)
功能:测试字符串中有效字符的个数(不含字符串结束标志 '\0' ),并将其作为函数返回值。/*源程序8-13*/
#include"stdio.h"
#include"string.h"
main()
{
intn;
charstr[40]="Clanguage";
n=strlen(str);
printf("Thelengthofthestringis%d\n",n);
}程序运行结果如下:
习题
1.编写函数fun,其首部为voidfun(char*s)。它的功能是:将s所指字符串中所有下标为奇数位置上的字母转换为大写(若该位置上不是字母,则不转换)。例如,若输入"abc4EFg",则应输出"aBc4EFg"。
2.假定输入的字符串中只包含字母和“*”号。编写函数fun,其首部为voidfun(char*s)。它的功能是:除了字符串前导的*号之外,将字符串中其他*号全部删除。在编写函数时,最好不使用C语言提供的字符串函数。例如,字符串中的内容为****A*BC*DEF*G*******
删除后,字符串中的内容应当是
****ABCDEFG
3.假定输入的字符串中只包含字母和*号。编写函数fun,其首部为voidfun(char*s)。它的功能是:将字符串中的前导*号全部移到字符串的尾部。例如,字符串中的内容为
*******A*BC*DEF*G****
移动后,字符串中的内容应当是
A*BC*DEF*G***********
在编写函数时,最好不使用C语言提供的字符串函数。
4.假定输入的字符串中只包含字母和*号。编写函数fun,其首部为voidfun(char*s)。它的功能是:使字符串的前导*号不得多于n个;若多于n个,则删除多余的*号;若少于或等于n个,则什么也不做;字符串中间和尾部的*号不删除。例如,字符串中的内容为
*******A*BC*DEF*G****
若n的值为4,则删除后,则字符串中的内容应当是
****A*BC*DEF*G****
若n的值为8,则字符串中的内容仍为
*******A*BC*DEF*G
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 宜宾小年活动策划方案
- 家庭垃圾清理活动方案
- 家庭餐桌礼仪活动方案
- 宾馆儿童半价活动方案
- 寿宴活动暖场活动方案
- 官方活动策划方案
- 小吃铺开张活动方案
- 小学入户宣传活动方案
- 家纺店线上活动策划方案
- 小学洗衣活动方案
- 苗木采购施工方案
- 【大单元】1《北京的春节》第2课时 教学设计
- 教育现象及问题分析
- 2024年新华东师大版七年级上册数学全册教案(新版教材)
- 2024年一级健康管理师考前冲刺必会试题库300题(含详解)
- 【8历期末】安徽省合肥市包河区2022-2023学年八年级下学期期末历史试题(含解析)
- 八年级历史下册核心知识点、难点、重点总结
- (高清版)JTGT D81-2017 公路交通安全设施设计细则
- 新概念马学智慧树知到期末考试答案章节答案2024年内蒙古农业大学
- 《临床试验生物样本伦理管理指南(征求意见稿)》
- MOOC 铁路站场及枢纽-华东交通大学 中国大学慕课答案
评论
0/150
提交评论