08第八章指针.ppt

上传人:s****8 文档编号:69577981 上传时间:2023-01-07 格式:PPT 页数:74 大小:692KB
返回 下载 相关 举报
08第八章指针.ppt_第1页
第1页 / 共74页
08第八章指针.ppt_第2页
第2页 / 共74页
点击查看更多>>
资源描述

《08第八章指针.ppt》由会员分享,可在线阅读,更多相关《08第八章指针.ppt(74页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、1/74第八章第八章 指针指针8.1 寻找保险箱密码寻找保险箱密码 8.2 角色互换角色互换8.3 冒泡排序冒泡排序8.4 加密变换问题加密变换问题 8.5 任意个整数求和问题任意个整数求和问题*2/74本章要点本章要点在变量、内存单元和地址之间是什么关系在变量、内存单元和地址之间是什么关系?如何定义指针变量,怎样才能使用指针变量如何定义指针变量,怎样才能使用指针变量?什么是指针变量的初始化什么是指针变量的初始化?指指针针变变量量的的基基本本运运算算有有哪哪些些?如如何何使使用用指指针针改改变变量的值变变量的值?指针作为函数参数的作用是什么?指针作为函数参数的作用是什么?如何通过指针实现函数调

2、用返回多个值如何通过指针实现函数调用返回多个值?如何利用指针实现内存的动态分配?如何利用指针实现内存的动态分配?3/748.1 寻找保险箱密码寻找保险箱密码指针指针变量变量的的定义定义密码存放在某个寄存箱内,如果我们知道这个寄存箱密码存放在某个寄存箱内,如果我们知道这个寄存箱的名字,就能够找到密码的名字,就能够找到密码如果不知道密码所在的寄存箱名字,知道该寄存箱的如果不知道密码所在的寄存箱名字,知道该寄存箱的地址也照样能够取出密码地址也照样能够取出密码如果寄存箱的地址也不知道,但是有另外一个地方存如果寄存箱的地址也不知道,但是有另外一个地方存放这个寄存箱的地址,也能顺藤摸瓜,间接找到密码放这个

3、寄存箱的地址,也能顺藤摸瓜,间接找到密码4/74一一.指针的概念指针的概念int x=20,y=1,z=155;printf(%d,x;)直接访问直接访问:通过变量名访问:通过变量名访问间接访问间接访问:通过另一个变量访问通过另一个变量访问把变量的地址放到另一变量中把变量的地址放到另一变量中使用时先找到后者使用时先找到后者再再从中取出前者的地址从中取出前者的地址1000 20 x1002 1 y1004 155 z2000 1000 px2002地址地址 指针变量指针变量 内存单元内存单元地址地址 内容内容 变量变量5/74 内存单元内存单元地址地址 内容内容 变量变量1000 20 x100

4、2 1 y1004 155 z2000 1000 px2002指针变量指针变量:存放地址的变量:存放地址的变量某个某个变量变量的地址的地址指向指向指针指针地址地址int x=20,y=1,z=155;printf(%d,x;)6/74指针变量所指向的变量的类型指针变量所指向的变量的类型指针变量的名字指针变量的名字二二.指针变量的定义指针变量的定义指针变量专门用来存放地址,因此必须定义为指针变量专门用来存放地址,因此必须定义为指针类型指针类型指针变量定义的一般形式指针变量定义的一般形式:类型标识符类型标识符 *标识符标识符例如:float*fp;int*p;都是合法的指针变量定义指针声明符指针声

5、明符注意:注意:int*p中,指针变量名是中,指针变量名是p,不是,不是*p*是指针声明符是指针声明符7/74变量的指针就是变量的地址变量的指针就是变量的地址指针变量是指向一个变量的地址的变量指针变量是指向一个变量的地址的变量可以用赋值语句使一个指针变量指向一个变量,可以用赋值语句使一个指针变量指向一个变量,通通过指针间接访问那个变量过指针间接访问那个变量指针变量中只能存放地址,因此,不能将其它非地址指针变量中只能存放地址,因此,不能将其它非地址类型的数据赋给指针变量类型的数据赋给指针变量有关地址的运算符有关地址的运算符:&-取地址运算符取地址运算符*-指针运算符指针运算符(即间接访问运算符即

6、间接访问运算符)指针的指针的基本运算包括基本运算包括有关地址的运算和指针赋值运算有关地址的运算和指针赋值运算三三.指针的基本运算指针的基本运算8/74&a*p-表示变量表示变量 a 的地址的地址(变量变量a的指针的指针)-表示指针变量表示指针变量 p 所指向的变量所指向的变量(地址地址p所指的单元中存放的值所指的单元中存放的值)*p就可以和普通变量一样参与运算或被赋值就可以和普通变量一样参与运算或被赋值例如例如:inti,*p;i=5;p=&i;2000(地址地址)p5(数据数据)*p地址地址2000i注意注意:1.:1.定义时定义时“*”“*”表示该变量是指针变量,而后面表示该变量是指针变量

7、,而后面的标识符就是该指针变量的变量名的标识符就是该指针变量的变量名 2.2.一个指针变量只能指向同一类型的变量一个指针变量只能指向同一类型的变量1.取地址运算和间接访问运算取地址运算和间接访问运算当当p=&i后,后,*p与与i相同相同例如例如:int*p,a;p=&a;*p=3;9/74inta=3,*pointer1,*pointer2;pointer1=&a;pointer2=pointer1;2.指针赋值运算指针赋值运算例如:例如:把把a的地址赋给的地址赋给pointer1,即即pointer1指向指向apointer2也指向也指向a&apointer1&aa3pointer2*poi

8、nter1*pointer2注意注意:1.:1.变量的地址只能赋给相同类型的指针变量变量的地址只能赋给相同类型的指针变量 2.2.相同类型的指针之间才能相互赋值相同类型的指针之间才能相互赋值10/74定义指针变量后,在没有给指针变量赋值之前,定义指针变量后,在没有给指针变量赋值之前,指针变量的值是不确定的指针变量的值是不确定的注意注意:不能使用没有赋值的指针不能使用没有赋值的指针在定义指针变量时可以对指针变量赋初值在定义指针变量时可以对指针变量赋初值例如:int a;int*p1=&a;int*p2=p1;四四.指针指针变量变量的的初始化初始化11/74main()inta,b;int*poi

9、nter1,*pointer2;a=100;b=10;pointer1=&a;pointer2=&b;printf(%d,%dn,a,b);printf(%d,%dn,*pointer1,*pointer2);1.&*pointer1-?2.*&a-?3.(*pointer1)+-?*pointer1+-?这里,由于这里,由于pointer1指向指向a,因此因此*pointer1的值的值就是变量就是变量a定义指向整型变量的指针变量定义指向整型变量的指针变量使使pionter1指向指向a使使pionter2指向指向b指针变量应用指针变量应用例:例:12/74p1p236abp&a&bmain()

10、inta,b,*p1,*p2,*p;scanf(%d,%d,&a,&b);p1=&a;p2=&b;if(ab)p=p1;p1=p2;p2=p;printf(a=%d,b=%dn,a,b);printf(max=%d,min=%dn,*p1,*p2);例例:输入整数输入整数a和和b,按大小顺序输出按大小顺序输出实际上没有交换实际上没有交换a和和b,而是使而是使p1指向大的数指向大的数,p2指向小的数指向小的数p1p2abp&a&a&b36&b&a13/74以下程序运行后以下程序运行后,a的值是:的值是:main()inta,k=4,m=6,*p1,*p2;p1=&k;p2=&m;a=p1=&m;

11、printf(“%d”,a);A)4B)1C)0D)运行时出错,运行时出错,a无定值无定值 14/74intx,*p;p=&x;则则&*p相当于相当于_A、pB、*pC、xD、*&x 下列程序段的输出结果是下列程序段的输出结果是_。int*p,*q,k=1,j=10;p=&j;q=&k;p=q;(*p)+;printf(%d,*q);A1 B2C10D11 15/74int*p,x;p=&x,则则(*p)+相当于相当于_。A、p+B、x+C、*(p+)D、&x+下列正确的定义是下列正确的定义是_。A、intx=3,*p=1;B、intx=3,*p;C、intx=3,*p=x;D、int*p=&

12、x=3;16/748.2 角色互换角色互换指针指针作为函数的参数作为函数的参数函数参数包括实参和形参,两者类型要一致函数参数包括实参和形参,两者类型要一致,可以是可以是指针类型。指针类型。指针作函数的参数时指针作函数的参数时,将一个变量的地址传送到函数中,将一个变量的地址传送到函数中,使实参和形参共用同一块内存单元。使实参和形参共用同一块内存单元。如果实参是某个变量的地址,相应的形参就是指针。如果实参是某个变量的地址,相应的形参就是指针。17/74main()inta,b,*pa,*pb;scanf(%d%d,&a,&b);pa=&a;pb=&b;if(ab)swap(pa,pb);print

13、f(%d%dn,a,b);printf(%d%dn,*pa,*pb);例如例如:用一个函数将两个整数用一个函数将两个整数a和和b按大小顺序输出按大小顺序输出swap(int*p1,int*p2)intt;t=*p1;*p1=*p2;*p2=t;交换两个指针所交换两个指针所指的单元中的值指的单元中的值12abpapbp1p221值传递,地值传递,地址未变,址未变,但存放的变量的值改变了但存放的变量的值改变了18/7412swap(intx,inty)intt;t=x;x=y;y=t;?main()inta,b,*pa,*pb;scanf(%d%d,&a,&b);pa=&a;pb=&b;if(ab

14、)swap(a,b);printf(%d%dn,a,b);printf(%d%dn,*pa,*pb);12abpapb21xy思考?思考?19/74swap(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;?main()inta,b,*pa,*pb;scanf(%d%d,&a,&b);pa=&a;pb=&b;if(ab)swap(pa,pb);printf(%d%dn,a,b);printf(%d%dn,*pa,*pb);思考?思考?p1p212abpapb值传递,形参指针的改变值传递,形参指针的改变不会影响实参不会影响实参20/74要通过函数调用来改变主调函数中某个变

15、量的值:要通过函数调用来改变主调函数中某个变量的值:(1)在主调函数中,将该变量的地址或者指向该变量的在主调函数中,将该变量的地址或者指向该变量的指针作为实参指针作为实参(2)在被调函数中,用指针类型形参接受该变量的地址在被调函数中,用指针类型形参接受该变量的地址(3)在被调函数中,改变形参所指向变量的值在被调函数中,改变形参所指向变量的值注意注意:1.:1.可以通过让实参指针变量和形参指针变量指向可以通过让实参指针变量和形参指针变量指向主调函数中的同一变量,在主调函数中获得该主调函数中的同一变量,在主调函数中获得该变量的新值变量的新值 2.2.不能通过改变形参指针的值来改变实参指针的不能通过

16、改变形参指针的值来改变实参指针的指向,因为,指针变量也是单向的指向,因为,指针变量也是单向的 值传递值传递 swap(int*p1,int*p2)int t;t=*p1;*p1=*p2;*p2=t;swap(int x,int y)int t;t=x;x=y;y=t;swap(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;21/74例:输入年和天数,输出对应的月和日。例:输入年和天数,输出对应的月和日。如:输入如:输入2000和和61,输出,输出3和和1分析:通过指针实现函数调用返回多个值分析:通过指针实现函数调用返回多个值 自定义函数自定义函数month_day(y

17、ear,yearday,*pmonth,*pday),用用2个指针作为函数的参数,带回个指针作为函数的参数,带回2个结果(个结果(月和日)月和日)#include void main()int day,month,year,yearday;void month_day(int year,int yearday,int*pmonth,int*pday);printf(input year and yearday:);scanf(%d%d,&year,&yearday);month_day(year,yearday,&month,&day);printf(%d-%dn,month,day);22/

18、74void month_day(int year,int yearday,int*pmonth,int*pday)int k,leap;int tab 213=0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31,;leap=year%4=0&year%100!=0|year%400=0;for(k=1;yearday tableapk;k+)yearday=yearday -tableapk;*pmonth=k;*pday=yearday;inputyearandyearday:2000613

19、-1monthdaypmonthpday3123/748.3 冒泡排序冒泡排序指针指针和和数组数组一一.指针、数组、地址间的关系指针、数组、地址间的关系数组的指针数组的指针数组元素的指针数组元素的指针数组元素的引用数组元素的引用-数组的起始地址数组的起始地址-数组元素的地址数组元素的地址-下标法、下标法、指针法指针法(指针法(指针法-通过指向数组元素的指针找到所需的元素)通过指向数组元素的指针找到所需的元素)数组名代表一个地址,它的值是数组首元素的地址,即数组的起始地址数组名代表一个地址,它的值是数组首元素的地址,即数组的起始地址例:例:inta10;a+i是距数组是距数组a的基地址的第的基地

20、址的第i个偏移,即元素个偏移,即元素ai的地址的地址任何由数组下标来实现的操作都能用指针来完成任何由数组下标来实现的操作都能用指针来完成数组名是一个特殊的固定地址,可以把它看作是常量指针数组名是一个特殊的固定地址,可以把它看作是常量指针24/741.指向数组元素的指针变量的指向数组元素的指针变量的定义与赋值定义与赋值指向数组元素的指针变量的定义指向数组元素的指针变量的定义与普通的指针变量的定义相同与普通的指针变量的定义相同a0a1ai.&a0&a1&aiap=a;或或p=&a0pinta10,i,*p,*p1;如果有如果有p1=&aip1例如:inta10;int*p;.p=&a0;把把a0元

21、素的地址赋给元素的地址赋给p,(即即p指向指向a数组的第数组的第0个元素个元素)等价于等价于p=a(因为数组名表因为数组名表示数组的首地址示数组的首地址)inta10;int*p=&a0;相当于相当于int*p;p=&a0;等价于等价于int*p=a;在定义指针变量时可以赋初值在定义指针变量时可以赋初值25/74注意注意:1.C语言中规定语言中规定p+1(或或p+)指向数组的下一个元素指向数组的下一个元素(并不是地址值简单加并不是地址值简单加1)当当p的初值为的初值为a的首地址时的首地址时,2.p+i或或a+i就是就是ai的地址,因为的地址,因为a代表了数组的首地址代表了数组的首地址3.*(p

22、+i)或或*(a+i)所指的数组元素就是所指的数组元素就是ai-变址运算符变址运算符4.指向数组的指针变量也可以带下标指向数组的指针变量也可以带下标,如如:*(p+i)等价于等价于pi2.通过指针引用数组元素通过指针引用数组元素int a10;int*p=a;.*p=1;对对p当前所当前所指的元素指的元素赋整数值赋整数值1p+1或或a+1pp+2或或a+2p+i或或a+i*(p+i)a数组数组p+9或或a+9a0a1a2aia926/74数组元素的引用可以用数组元素的引用可以用(1)下标法:)下标法:ai 或或 (2)指针法:指针法:*(a+i)或或*(p+i)例如例如:inta10,*p,i

23、;输出数组输出数组a的元素的元素for(i=0;i10;i+)printf(%d ,ai);for(i=0;i10;i+)printf(%d ,*(a+i);p=a;for(i=0;i10;i+)printf(%d ,*(p+i);for(p=a;pa+10;p+)printf(%d ,*p);下标法下标法:指针法指针法:for(p=a;ap+10;a+)printf(%d,*a)?如果如果X注意注意:*p+由于由于*和和+的优先级相同,的优先级相同,结合方向同为自右至左,因此等结合方向同为自右至左,因此等价于价于*(p+),作用是先得到作用是先得到p所指向的变量的所指向的变量的值值(即即*p

24、),然后再使然后再使p=p+127/743.指针的算术运算和比较运算指针的算术运算和比较运算double*p,*q;lq-p两个相同类型的指针相减,表示它们之间相隔的两个相同类型的指针相减,表示它们之间相隔的存储单元的数目存储单元的数目lp+1指向下一个存储单元指向下一个存储单元lpq两个相同类型指针可以用关系运算符比较大小两个相同类型指针可以用关系运算符比较大小C C语言中指针的算术运算包括语言中指针的算术运算包括:两个相同类型的指针相减两个相同类型的指针相减指针加上或减去一个整数指针加上或减去一个整数其他操作其他操作(指针相加、相乘和相除,或指针加上和减指针相加、相乘和相除,或指针加上和减

25、去一个浮点数去一个浮点数)都是非法的。都是非法的。例如:例如:28/74#include void main(void)double a2,*p,*q;p=&a0;q=p+1;printf(%dn,q-p);printf(%dn,(int)q-(int)p);pq3000 a0地址 内容 数组元素3008 a1 aa+1指针指针p和和q之间元素的个数之间元素的个数指针指针p和和q之间的字节数之间的字节数地址值地址值整数整数18例如:例如:29/74设变量定义为设变量定义为inta2=1,3,*p=&a0+1;则则*p的值是的值是_。A、2B、3C、4D、&a0+1 inta4;则表达式则表达式

26、_不符合不符合C语言语法。语言语法。A、*aB、a0C、aD、a+若已定义若已定义:inta9,*p=a;并在以后的语句中未改变并在以后的语句中未改变p的值,的值,不能表示不能表示a1地址的表达式是地址的表达式是_。A、p+1B、a+1C、a+D、+p 30/74如果数组如果数组a定义为定义为inta32=1,2,3,4,5,6,那么,那么,a0不是不是int类型的数组元素。类型的数组元素。A、正确、正确B、错误、错误语句语句“inta10,*p=a;”表示表示*p被赋初值为被赋初值为a数组的首地址。数组的首地址。A、正确、正确B、错误、错误 31/74二二.数组名作为函数的参数数组名作为函数

27、的参数数组元素作为函数数组元素作为函数实参实参时,函数时,函数形参形参为变量为变量与变量作为函数实参相同,值传递与变量作为函数实参相同,值传递double fact(int n);void main()int i,n=5;double sum;sum=0;for(i=1;i=n;i+)sum=sum+fact(i);printf(sum=%en,sum);double fact(int n)int i;double result=1;for(i=1;i=n;i+)result=result*i;return result;fact(ai-1);inta5=1,4,5,7,9;32/74数组名作

28、函数参数时数组名作函数参数时,实参数组向形参数组传递的是数组实参数组向形参数组传递的是数组的首地址,因此形参数组中的元素的值发生变化后的首地址,因此形参数组中的元素的值发生变化后,返回返回调用函数时,实参数组的相应元素的值也发生变化调用函数时,实参数组的相应元素的值也发生变化(因为实参数组和形参数组共享同一段内存因为实参数组和形参数组共享同一段内存)数组名是指针常量,相当于指针作为函数的参数数组名是指针常量,相当于指针作为函数的参数数组名数组名做为实参,形参是做为实参,形参是指针变量指针变量(数组)(数组)1.形参和实参都用数组名形参和实参都用数组名,2.实参用数组名实参用数组名,形参用指针变

29、量形参用指针变量,3.实参和形参都用指针变量实参和形参都用指针变量,4.实参用指针变量实参用指针变量,形参用数组名形参用数组名,由于实参和形参是地址传递,因此函数的实参和形参的对由于实参和形参是地址传递,因此函数的实参和形参的对应关系有应关系有:33/74注意注意:指针变量作实参时指针变量作实参时,必须指针变量有确定值必须指针变量有确定值,指向一个已定义的数组指向一个已定义的数组int sum(int*array,int n)int i,s=0;for(i=0;in;i+)s+=arrayi;return(s);*(array+i)intarrayvoid main()int i;int b5

30、=1,4,5,7,9;printf(%dn,sum(b,5);void main()int i,*p;int b5=1,4,5,7,9;p=b;printf(%dn,sum(p,5);34/74int sum(int*array,int n)int i,s=0;for(i=0;in;i+)s+=arrayi;return(s);void main()int i;int b5=1,4,5,7,9;printf(%dn,sum(b,5);b b0b4arraysum(b,5)b0+b1+.+b4sum(b,3)b0+b1+b2sum(b+1,3)b1+b2+b3sum(&b2,3)b2+b3+b4

31、35/74数组名做为函数的参数,在函数调用时,将实参数组数组名做为函数的参数,在函数调用时,将实参数组首元素的地址传给形参(指针变量),因此,形参也首元素的地址传给形参(指针变量),因此,形参也指向实参数组的首元素。如果改变形参所指向单元的指向实参数组的首元素。如果改变形参所指向单元的值,就是改变实参数组首元素的值。值,就是改变实参数组首元素的值。或:形参数组和实参数组共用同一段存贮空间,如果形参或:形参数组和实参数组共用同一段存贮空间,如果形参数组中元素的值发生变化,实参数组中元素的值也同数组中元素的值发生变化,实参数组中元素的值也同时发生变化。时发生变化。a a0a4p36/74例:例:将

32、数组元素逆序存放将数组元素逆序存放#includevoidmain()inti,a10,n;voidreverse(intp,intn);scanf(%d,&n);for(i=0;in;i+)scanf(%d,&ai);reverse(a,n);for(i=0;in;i+)printf(%dt,ai);voidreverse(intp,intn)inti,j,t;for(i=0,j=n-1;ij;i+,j-)t=pi;pi=pj;pj=t;voidreverse(int*p,intn)int*pj,t;for(pj=p+n-1;ppj;p+,pj-)t=*p;*p=*pj;*pj=t;用数组用

33、数组用指针用指针程序:程序:37/74例:冒泡法排序例:冒泡法排序voidsort(int*array,intn)int i,j,t;for(i=1;in;i+)for(j=0;jarrayj+1)t=arrayj;arrayj=arrayj+1;arrayj+1=t;void main()int i,a10;for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);for(i=0;istr3+0-str2+0-str1如果改为:char str13;scanf(%s,str);输入:Howareyou?只将第一个空格前的字符只将第一个空格前的字符How送到送到str中,

34、并加上中,并加上0用数组名用数组名,而且不要加而且不要加地址符地址符&因为数组名代表了该因为数组名代表了该数组的起始地址数组的起始地址43/742.2.字符串的复制、连接、比较、求字符串长度字符串的复制、连接、比较、求字符串长度字符串复制:字符串复制:strcpy(str1,str2)字符串连接:字符串连接:strcat(str1,str2)字符串比较:字符串比较:strcmp(str1,str2)求字符串长度:求字符串长度:strlen(str)函数原型函数原型在在string.h44/74(1)字符串复制函数字符串复制函数strcpystrcpy(str1,str2);将字符串将字符串st

35、r2(包括结束标志包括结束标志0)拷贝到字符数组拷贝到字符数组str1中中其中其中:字符数组字符数组str1必须是字符数组名的形式必须是字符数组名的形式字符串字符串str2可以是字符数组名或字符串常量可以是字符数组名或字符串常量static char str120;static char str220=“happy”;strcpy(str1,str2);strcpy(str1,“world”);注意注意:字符数组字符数组1必须足够大必须足够大 不能用赋值语句直接将一个字符串赋给一个字符不能用赋值语句直接将一个字符串赋给一个字符数组,只能用数组,只能用strcpy函数函数0happy0str1中

36、中:str2中中:happy0str1中中:world0str1中中:45/74例:#include“stdio.h”#include“string.h”void main()char str120,str220;gets(str2);strcpy(str1,str2);puts(str1);不用函数如何实现不用函数如何实现?1234ABC1234ABC46/74(2)字符串连接函数字符串连接函数strcat 连接两个字符串连接两个字符串str1和和str2,并将结果放入并将结果放入str1注意注意:字符数组字符数组str1必须足够大必须足够大连接时将自动取消第一个字符串后面的结束标志连接时将

37、自动取消第一个字符串后面的结束标志0strcat(str1,str2);#include stdio.h#include string.hvoid main()char str180,str220;gets(str1);gets(str2);strcat(str1,str2);puts(str1);str1中:中:Letus0str2中:中:go.0str1中:中:Letusgo.0str2中:中:go.0Letusgo.不用函数如何实现不用函数如何实现?Letusgo.47/74(3)字符串比较函数字符串比较函数strcmpstrcmp(str1,str2)比较比较两个字符串两个字符串str

38、1和和str2的大小的大小规则:按字典序规则:按字典序(ASCII码序码序)如果如果str1和和str2相等,返回相等,返回0;如果如果str1大于大于str2,返回一个正整数;返回一个正整数;如果如果str1小于小于str2,返回一个负整数;返回一个负整数;staticchars120=sea;strcmp(s1,Sea);strcmp(Sea,Sea);strcmp(Sea,Sea);正整数正整数负整数负整数0注意注意:两个字符串比较不能用关系运算符,只能用两个字符串比较不能用关系运算符,只能用strcmp函数函数48/74例:#include“stdio.h”#include“strin

39、g.h”main()int res;char s120,s220;gets(s1);gets(s2);res=strcmp(s1,s2);printf(“%d”,res);不用函数如何实现不用函数如何实现?49/74(4)字符串长度函数字符串长度函数strlen计算字符串的有效长度,不包括计算字符串的有效长度,不包括0strlen(str)static char str20=“How are you?”strlen(“hello”)的值是:strlen(str)的值是:512不用函数如何实现不用函数如何实现?注意:注意:strlen(str)与与sizeof(str)的区别的区别122050/

40、74函函数数功功能能头文件头文件puts(str)输出字符串输出字符串stdio.hgets(str)输入字符串(回车间隔)输入字符串(回车间隔)strcpy(s1,s2)s2s1strcat(s1,s2)s1+s2s1strcmp(s1,s2)若若s1=s2,函数值为函数值为0若若s1s2,函数值函数值0string.h若若s1s2,函数值函数值0strlen(str)计算字符串的有效长度,计算字符串的有效长度,(不包括(不包括0)常用字符串处理函数常用字符串处理函数51/74例例:求最小的的字符串求最小的的字符串#include void main()int i;char sx80,smi

41、n80;scanf(%s,sx);strcpy(smin,sx);for(i=1;i 5;i+)scanf(%s,sx);if(strcmp(sx,smin)0)strcpy(smin,sx);printf(min is%sn,smin);toolkeyaboutzoosea minisabout 52/74三三.字符串和字符指针字符串和字符指针1.字符串表示形式字符串表示形式:(1)用字符数组用字符数组例如:staticcharstring=theCprogram;这里这里string是数组名是数组名,代表代表这个字符数组的首地址这个字符数组的首地址*(string+i)表示表示string

42、i(2)用字符指针用字符指针例如:char*string=theCprogram;等价于:char*string;string=theCprogram;字符串常量按字符数组处字符串常量按字符数组处理理,在内存中开辟了一个字在内存中开辟了一个字符数组来存放字符串常量符数组来存放字符串常量定义的指针变量定义的指针变量string指向字符串的首地址指向字符串的首地址定义一个指向字符的指针定义一个指向字符的指针把该字符串的首地址赋给把该字符串的首地址赋给string由于可以用数组或指针来表示字符由于可以用数组或指针来表示字符串,因此对字符串中的字符的存取串,因此对字符串中的字符的存取可以用下标法,也可

43、以用指针法。可以用下标法,也可以用指针法。53/74用字符数组和字符指针都可以处理字符串用字符数组和字符指针都可以处理字符串 char sa =array;char*sp=point;printf(%s,sa);printf(%s,sa+1);printf(%s,sp+2);printf(%s,string+3);printf(%s,输出参数输出参数);给出起始位置(地址)给出起始位置(地址)0控制结束控制结束rray int ing array54/742.字符指针和字符数组的区别字符指针和字符数组的区别(1)字符数组由若干元素组成,每个元素中存放一个字符字符数组由若干元素组成,每个元素中存

44、放一个字符 字符指针变量中存放字符串的首地址字符指针变量中存放字符串的首地址char sa =This is a string.;字符数组字符数组sa在内存中占用了一块连续的单元,有确定的在内存中占用了一块连续的单元,有确定的地址,每个元素放一个字符,字符串就存放在数组中地址,每个元素放一个字符,字符串就存放在数组中char*sp=This is a string.;字符指针字符指针sp占用一个可以存放地址的内存单元,存储字符占用一个可以存放地址的内存单元,存储字符串首字符的地址,而不是将字符串放到字符指针变量中去串首字符的地址,而不是将字符串放到字符指针变量中去This is a strin

45、g.spThis is a string.sa55/74(2)字符数组只能对各元素赋值,字符指针变量可以用赋字符数组只能对各元素赋值,字符指针变量可以用赋值语句赋值值语句赋值(将字符串的首地址赋给该指针变量将字符串的首地址赋给该指针变量)(3)字符数组可以在定义时整体赋初值,但不能在赋值语句字符数组可以在定义时整体赋初值,但不能在赋值语句中整体赋值,只能用字符串拷贝函数进行整体复制中整体赋值,只能用字符串拷贝函数进行整体复制char sa =This is a string.;char*sp=This is a string.;sa1=a;sp=new string.;strcpy(sa,He

46、llo);(4)数组名代表该数组的起始地址,它的值不能改变,数组名代表该数组的起始地址,它的值不能改变,指针变量的值可以改变指针变量的值可以改变56/74(5)数组一经定义数组一经定义,就有了确定的内存单元就有了确定的内存单元 字符指针变量定义后,虽然也分配了内存单元,在没有字符指针变量定义后,虽然也分配了内存单元,在没有对指针变量赋初值之前,这个单元中没有一个确定的地对指针变量赋初值之前,这个单元中没有一个确定的地址值,因此该指针具体并未指向某个字符数据。址值,因此该指针具体并未指向某个字符数据。不要引用未赋值的指针不要引用未赋值的指针在对指针赋值前,它的值是不确定的。在对指针赋值前,它的值

47、是不确定的。char*p;scanf(%s,p);可能出现难以预料的结果可能出现难以预料的结果char*s,str20;s=str;scanf(%s,s);是正确的是正确的char*p=NULL;57/743.字符数组和字符指针字符数组和字符指针例:编写自定义函数例:编写自定义函数strcpy、strcmp和和strlen,要求分别要求分别用字符数组和字符指针实现用字符数组和字符指针实现void strcpy(char to,char from)int i;for(i=0;fromi!=0;i+)toi=fromi;toi=0;void strcpy(char to,char from)int

48、 i=0;while(toi=fromi)!=0)i+;toi=fromi 1.字符串拷贝函数字符串拷贝函数strcpy58/74void strcpy(char to,char from)int i=0;while(toi=fromi)i+;void strcpy(char*to,char*from)while(*to=*from)to+;from+;数组:改变下标数组:改变下标指针:直接移动指针指针:直接移动指针void strcpy(char*to,char*from)while(*to+=*from+);59/742.字符串比较函数字符串比较函数strcmpint strcmp(cha

49、r s,char t)int i;for(i=0;si!=0;i+)if(si!=ti)break;return si-ti;int strcmp(char*s,char*t)for(;*s!=0;s+,t+)if(*s!=*t)break;return(*s-*t);60/743.字符串长度函数字符串长度函数strlenint strlen(char str)int i=0;while(stri!=0)i+;return i;int strlen(char*str)char*t=str;while(*str!=0)str+;return str-t;61/74下面程序的输出结果是下面程序的输

50、出结果是.main()inti=3,j=2;char*a=“DCBA”;printf(“%c%c”,ai,aj);ABa3,a262/74下面程序的输出结果是下面程序的输出结果是.charb=“ABCD”;main()char*chp;for(chp=b;*chp;chp+=2)printf(“%s”,chp);ABCDCD“ABCD 0”*chp 为为 0 时(即时(即0),循环,循环结束结束chp打印打印A的地址的地址ABCDC的地址的地址CD0的地址的地址63/74以下程序运行后,输出结果是以下程序运行后,输出结果是main()char*s=“abcde”;s+=2;printf(“%l

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 生活常识

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com