




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第一章C语言概述第二章数据类型、运算符与表达式第三章最简单的C程序设计第四章逻辑运算和判断选取控制第五章循环控制第六章数组第八章编译预处理第九章指针第十章结构体与共用体第十二章文件的基本操作第十三章位运算§9.4字符串指针和指向字符串的指针变量一、字符串指针的定义例:#include<stdio.h>
main()
{charp;
chars[]="Iamastudent!";
p=s;
printf("p=%s",p);}形式charp;表示p为指针变量,可指向一个字符串的首地址。运行结果为:p=Iamastudent!可以在定义的时候赋初值:
main()
{charp="Iamastudent!";
…或者:main() {charp; p="Iamastudent!"; …则:p代表I(p+3)代表m1.“…”一个串名代表示该串的首地址2.在输入(scanf)和输出(printf)中,也可用%s将整个串一次输入/输出例:将字符串a复制到字符串b1)用字符数组实现1)main(){chara[]="Iamateacher!";charb[20];inti; for(i=0;(a+i)!='\0';i++)
(b+i)=(a+i);
(b+i)='\0'; printf("stringais:%s\n",a); printf("stringbis:"); for(i=0;b[i]='\0';i++) printf("%c",b[i]); printf("\n");}等价于:printf("stringbis:%s\n",b);运行结果:stringais:Iamateacher!stringbis:Iamateacher! main() {chara[]="Iamateacher!"; charb[20],p1,p2; p1=a;p2=b; for(;p1!='\0';p1++,p2++)
p2=p1;
p2='\0'; printf("stringais:%s\n",p1);printf("stringbis:%s\n",p2);}2)用指针变量实现运行结果:stringais:Iamateacher!stringbis:Iamateacher!请思考:对上面的程序作如下改变:main(){chara[]="Iamateacher";charb[20],*p1,*p2;p1=a;p2=b;p2=p1;则b数组中的内容是否已复制了a数组中的内容结论:p1=a;p2=a;p1a;p2b;p1a;p2p2=p1后;b二、字符串指针作函数参数例:用函数调用实现字符串的复制
与数值变量指针一样,字符串指针,字符串数组均可作为函数参数作用:可在函数中改变实参内容。方法:(1)字符数组作参数
voidcopy_string(from,to) charfrom[],to[]; {inti=0; while(from[i]!='\0'){to[i]=from[i];i++}to[i]='\0';}main(){chara[]="Iamateacher";charb[]="Youareastudent";printf("string_a=%s\nstring_b=%s\n",a,b);copy_string(a,b);printf("\nstring_a=%s\nstring_b=%s\n",a,b)}运行结果:string_a=Iamateacher string_b=Youareastudent string_a=Iamateacher string_b=Iamateacher 可以在main中使用字符串指针:
chara="Iamateacher".;
charb="Youareastudent."…但以字符串的方式输出b中内容时,遇到第一个'\0'时结束。实际上,数组b中的内容为:Iamateacher\0nt\0(2)形参用字符指针变量
voidcopy_string(from,to)charfrom,to;{for(;from!='\0';from++,to++)
to=from;
to='\0';}或:将for改用whilewhile(from!='\0'){to=from;to++;from++;}或:while((to=from)!='\0'){from++;to++;}或:while((to++=from++)!='\0');实际上'\0'的ASCII码为0,故可将
while((to++=from++)!=0)简化为:while(to++=from++)字符数组作参数的实、形参调用的四种情况 实参 形参 数组名 数组名 数组名 指针型 指针型 指针型……
指针型 数组名小结:三、字符数组与字符指针变量若用指针变量,即可将整个字符串赋给指针名:
charaa="GoodMorning!";
前面介绍中,字符数组与字符指针变量在使用中具有一定的统一性,但它们之间仍有以下区别:1.赋值方式不同:对字符数组只能对各个元素赋值,不可将整个串赋给数组名,即:chara[14];a="GoodMorning!";—是错误的2.定义数组后,系统给它分配内存单元。具有确定的内存地址,但指针变量定义后,若未对它赋地址,则它并不指向任何单元。
如果:chara;scanf("%s",a);
则:系统十分危险,由于a可能指向一个系统单元,因此,就会破坏该单元的值。应改为:charstr[10],a;a=&str[0];或a=str;scanf("%s",a);3.指针变量的值可以改变,而数组名(首地址)是不可改变的,即:在程序中不可直接对数组名赋值。下面的用法不允许:
charstr[]="Good!"; str=str+7;4.指针变量在确定了值后,可以采用数组元素的方法引用指向的值:
chara[]="Good"; charb=&a[0]; printf("%c",b[2]):5.可用指针变量(代表一个字符串)存放格式控制序列,即:
charformat format="a=%d,b=%f\n"; printf(format,a,b);
当然,format也可为一数组,但赋值时不如指针变量那样方便。§9.5函数的指针及指向函数的指针变量
基本概念:前面已述,每一个变量有地址,于是可用一个指针变量来保存,而一个函数实际上为存放在内存中的一段程序,它有一个入口地址––––称为函数的指针。存放函数指针的变量–––指向函数的指针变量。一、用函数指针变量调用函数1.函数指针变量的定义形式:类型标识符(变量名)()例:int(p)();表示p为一个函数指针变量,用于存放一个函数的入口地址,但该函数的返回值必须为int型。2.给函数指针变量赋值函数指针变量=函数名;它不是实参,不是调用,而是将入口地址赋给该变量。3.通过函数指针变量调用函数的方法
(函数指针变量名)(实参表列)例:求a、b中最大者函数。intmax(x,y)intx,y;{intz;z=(x>y)?x:y;return(z);}main(){intmax();int(p)();
inta,b,c;p=max;scanf("a=%d,b=%d",&a,&b);c=(p)(a,b)printf("maxvalue=%d",c)/*将p指向函数max*//*调用函数*/二、函数指针变量作为函数参数
意义:当一个函数被调用后,执行过程中可以根据实参的函数名来调用不同的函数。前面介绍过:简单变量、数组名、指针变量均可作为函数的参数。可以用函数指针变量作为函数的参数。例:sub(x1,x2)int(x1)(),(x2)();{inta,b,i,j;a=(x1)(i);b=(x2)(i,j)
}于是,可用sub(f1,f2)或sub(f3,f4)调用sub,表示执行sub时,根据实参传递过来的函数入口地址而调用f1,f2或f3,f4.例2.
设计一个函数process,每次实现不同的功能,当用不同的函数名作实参调用process时,process再去调用相应的函数。程序如下:
#include<stdio.h> main() {intmax(),min(),add(); inta,b; printf("enteraandb:"); scanf("%d,%d",&a,&b); printf("max="); process(a,b,max); printf("min=") process(a,b,min); printf("sum="); process(a,b,add); } max(x,y) intx,y; {intz; if(x>y)z=x; elsez=y; return(z); } min(x,y) intx,y; {intz; if(x<y)z=x; elsez=y; return(z); } add(x,y) intx,y; {intz; z=x+y; return(z); }process(x,y,fun)intx,y;int(*fun)();{intresult;result=(*fun)(x,y);printf("%d\n",result);}注:当用函数名作参数时,不论函数返值类型如何均应作说明,以与变量名相区别。运行情况如下:
enteraandb:2,6 max=6 min=2 sum=8§9.6返回指针值的函数
既然函数返回值可以是整、实型等数据。当然也可以是指针值,只是函数定义形式略有不同:例:
有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数来实现。类型标识符函数名(形参表列) float*search(float(*pointer[4],intn);); float*p; inti,m; printf("enterthenumberofstudent:"); scanf("%d",&m); printf("ThescoresofNo.%dare:\n",m);程序如下:{staticfloatscore[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};main() p=search(score,m);/*函数调用*/ for(i=0;i<4;i++) printf("%5.2f\t",*(p+i)); }float*seaarch(pointer,n)/*返回指针值的函数*/ float(*pointer)[4]; intn; {float*pt; pt=*(pointer+n); return(pt); }运行情况如下:
enterthenumberofstudent:1 ThescoresofNo.1are: 56.0089.0067.0088.00§9.7指针数组和指向指针的指针一、指针数组1.定义形式类型说明符数组名[常量]数组–––同种类型的数据集合。当每一个元素均为指针类型数据时,该数组被称为指针数组。例:intp[10];p为指针型数组,其每一个元素为一指针型变量。用来存入一组地址。灵活。
字符串长度不一,于是只得以最长字符串的长度作为二维数组列数,造成空间浪费。一般情况下,存放一组字符串,如一组书名,也可用二维字符数组存放,但存在二个问题:2.优越性如:存放一组字符串如:Applicationofcomputer\0English\0
用指针数组(一维)保存各字符串首地址,且交换时只需交换指针数组各元素––首地址即可解决上述二个问题。
在对字符串排序时,若交换数组元素,时间太长。例:将若干字符串按字母顺序(由小到大)输出。#include<stdio.h>#include<string.h> main() {voidsort(); voidprint(); staticchar*name[]={"Followme","BASIC","GreatWall","FORTRAN","Computerdesign"}; inti;n=5;
sort(name,n);print(name,n);}
printf("Beforesort:\n");
for(i=0;i<5;i++)
printf("mane[%d]=%s\n",i,name[i]);voidsort(name,n) char*name[];intn; {char*temp; inti,j,k;for(i=0;i<n-1;i++) {k=i; for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0)k=j; if(k!=i) {temp=name[i],name[i]=name[k];name[k]=temp;} }}} voidprint(name,n) char*name[];intn; {inti;printf("Aftersort:\n"); for(i=0;i<n;i++) printf("name[%d]=%s\n",i,name[i]);}运行结果为:Beforesort:name[1]=BASICname[2]=GreatWallname[3]=FORTRANname[4]=ComputerdesignAftersort:name[1]=Computerdesignname[2]=FORTRANname[3]=Followmename[4]=GreatWallname[0]=Followmename[0]=BASIC
一个数据变量有地址,可用一指针变量来存放该地址。那么一指针变量也有地址,可否用另一个指针变量来存放?回答是肯定的。&p&xpppx定义形式:intp,pp;二、指向指针的指针将指针变量的概念深化:例:
main() {staticchar*name[]={"Followme","BASIC","GreatWall","FORTRAN","Computerdesign"}; char**p; inti; for(i=0;i<5;i++) {p=name+i; printf("%s\n",*p);} }运行结果如下:
Followme BASIC GreatWall FORTRAN Computerdesignname[1]name[0]name[2]name[3]name[4]a[1]=3a[0]=1a[2]=5a[3]=7a[4]=9p注意:一组字符串只能用指针数组存放:
charname[]={"Good","Bad","Are","Teacher",};于是每一个元素name[i]为字符串指针变量
charp;p=&name[i];或p=name+i;则:
p就表示第i个字符串的首地址
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025标准网签版建筑工程合同模板
- 2025企业租赁合同协议标准版
- 2025年降酶退黄类药物合作协议书
- 2025技术转让合同范本(中英文对照)
- 2025年磐安县农产品收购合同
- 2025个人住宅庭院景观规划合同
- 2025二级建造师建筑实务知识点:合同价款约定详解
- 2025私营企业员工试用期合同模板
- 2025年外贸合同法律风险评估
- 2025年叔丁基苯酚项目合作计划书
- 软件质量证明书
- 高考标准化考场建设方案详细
- 人民医院肿瘤科临床技术操作规范2023版
- 高压-引风机电机检修文件包
- 2023届物理高考二模考前指导
- GB/T 39486-2020化学试剂电感耦合等离子体质谱分析方法通则
- GB/T 11085-1989散装液态石油产品损耗
- GXH-3011A1便携式红外线CO分析仪
- NYT 393-绿色食品 农药使用准则
- 2022年四川省阿坝州中考数学试卷及解析
- 综采工作面末采安全技术措施
评论
0/150
提交评论