资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,Chap,8 指针,8.1 寻找保险箱密码,8.2,指针作为函数参数,8.3 冒泡排序,8.4 加密变换问题,8.5 任意个整数求和问题*,本章要点,变量、内存单元和地址之间是什么关系?,如何定义指针变量,怎样才能使用指针变量?,什么是指针变量的初始化?,指针变量的基本运算有哪些?如何使用指针操作所指向的变量?,指针作为函数参数的作用是什么?,如何使用指针实现函数调用返回多个值?,如何利用指针实现内存的动态分配?,8.1,寻找保险箱密码,一个关于特工008寻找保险箱密码的故事,关键点分析,得到线索:0217单元的“虎跑号”寄存箱,提示地址:1976单元,找到目标:“龙井号”寄存箱,取出内容:911,8.1 寻找密码的途径分析,密码911存放在某个寄存箱内,如果我们知道这个寄存箱的名字,就能够找到密码,如果不知道密码所在的寄存箱名字,知道该寄存箱的地址也照样能够取出密码,如果寄存箱的地址也不知道,但是有另外一个地方存放这个寄存箱的地址,就能顺藤摸瓜,间接找到密码,8.1 密码存放示意图,龙井号,911,1976,虎跑号,1976,0217,名字,虎跑号,龙井号,地址,0217,1976,内容,1976,911,例8,-1,利用指针模拟寻找保险箱密码的过程,获取密码的两种方法,int,main(void),int,key=911;/*,变量,key,存放密码,*/,int,*,addr,=,NULL,;/*,变量,addr,存放地址,*/,addr,=,/*,将,key,的地址赋给,addr,*/,/*,通过变量,key,输出密码值,*/,printf(The,key is:%dn,key);,/*,通过变量,key,的地址来输出密码值,*/,printf(If,I know the address of the key,I also can get it:%dn,*,addr,);,return 0;,The key is:911,If I know the address of the key,I also can get it:911,8.1.2 地址和指针,指针,的,概念,内存单元,地址 内容,变量,int,x=20,y=1,z=155;,printf(%d,x;),直接访问,:通过变量名访问,间接访问,:,通过,另一个变量访问,把变量的地址放到另一变量中,使用时先找到后者,再,从中取出前者的地址,1000 20,x,1002 1,y,1004 155,z,2000 1000,p,2002,地址,指针变量,指针,内存单元,地址 内容,变量,int,x=20,y=1,z=155;,printf(%d,x;),1000 20,x,1002 1,y,1004 155,z,2000 1000,p,2002,地址,指针变量,指针变量,:存放地址的变量,某个,变量,的地址,指向,指针变量所指向的变量的类型,int,*p;,p,是整型指针,指向整型变量,float*,fp,;,fp,是浮点型指针,指向浮点型变量,char*cp;,cp,是字符型指针,指向字符型变量,类型名,*,指针变量名,指针声明符,8.1.3 指针变量的定义,指针变量的定义,类型名,*,指针变量名,int,*,p,;,指针变量名是,p,,,不是,*,p,*,是指针声明符,int,k,*p1,*p2;,等价于:,int,k;,int,*p1;,int,*p2;,8.1.4,指针的基本运算,*,:,间接访问运算符,,,访问指针所指向的变量,*,p,:,指针变量,p,所,指向的,变量,a,3,&,a,p,*,p,如果指针的值是某个变量的地址,通过指针就能,间接访问,那个变量。,1,、取地址运算和间接访问运算,&,取地址运算符,,,给出变量的地址,int,*p,a=3;,p=&a,;,把,a,的地址赋给,p,,即,p,指向,a,指针变量的类型和它所指向变量的类型相同,#include,int,main(void),int,a=3,*p;,p=,printf,(,“,a=%d,*p=%dn,”,a,*p);,*,p=10;,printf(,a,=%d,*p=%dn,a,*p);,printf(,Enter,a:,);,scanf(,%d,printf(,a,=%d,*p=%dn,a,*p);,(*p)+;,printf(,a,=%d,*p=%dn,a,*p);,return 0;,例8-2,指针取地址运算和间接访问运算,a,3,&,a,p,*,p,a=3,*p=3,a=10,*p=10,Enter a:,5,a=5,*p=5,a=6,*p=6,a,3,&,a,p,*,p,(1)当,p=&a,后,*,p,与,a,相同,(2),int,*,p,;,定义,指针,变量,p,*,p,=10;,指针,p,所指,向,的变量,,,即,a,(3),&*,p,与&,a,相同,,,是,地址,*&,a,与,a,相同,,,是,变量,(4)(*,p)+,等价于,a+,将,p,所指,向,的变量值加1,*,p+,等价于,*(,p+),先取,*,p,,然后,p,自加,,此时,p,不再指向,a,说明,int,a=1,x,*p;,p=,x=*p+;,b,2,&,b,p2,*,p2,a,1,&,a,p1,*,p1,2,1,#include,int,main(void),int,a=1,b=2,t;,int,*p1,*p2;,p1=,printf,(,a=%d,b=%d,*p1=%d,*p2=%dn,a,b,*p1,*p2);,t=*p1;*p1=*p2;*p2=t;,printf,(,a=%d,b=%d,*p1=%d,*p2=%dn,a,b,*p1,*p2);,return 0;,例8-3 通过,指针,改变,变量的值,a=1,b=2,*p1=1,*p2=2,a=2,b=1,*p1=2,*p2=1,2、赋值运算,a,3,&,a,p1,&,a,p2,*,p1,*p2,int,a=3,*p1,*p2;,p1=,把,a,的地址赋给,p1,,即,p1,指向,a,p2=p1;,p2,也指向,a,相同类型的指针才能相互赋值,b,4,&,b,p2,*,p2,a,2,&,a,p1,*,p1,6,c,&,a,&,c,例8-4,指针,赋值,int,main(void),int,a,b,c,*p1,*p2;,a=2;b=4;c=6;,p1=,printf,(,a=%d,b=%d,c=%d,*p1=%d,*p2=%dn,a,b,c,*p1,*p2);,p2=p1;p1=,printf,(,a=%d,b=%d,c=%d,*p1=%d,*p2=%dn,a,b,c,*p1,*p2);,return 0;,*,p2,*,p1,a=2;b=4;c=6;,*p1=2,*p2=4,a=2;b=4;c=6;,*p1=6,*p2=2,例8-5,int,main(void),int,a=1,b=2;,int,*p1=,printf,(a=%d,b=%d,*p1=%d,*p2=%dn,a,b,*p1,*p2);,pt=p1;p1=p2;p2=pt;,printf,(“a=%d,b=%d,*p1=%d,*p2=%dn”,a,b,*p1,*p2);,return 0;,8.1.5,指针,变量,的,初始化,p1,b,2,&,b,p2,*,p2,a,1,&,a,*,p1,pt,b,2,&,a,p2,*,p1,a,1,&,b,p1,*,p2,pt,&,a,a=1;b=2;*p1=1,*p2=2,a=1;b=2;*p1=2,*p2=1,对指针的操作,/,对指针所指向变量的操作,*,p1,和*,p2,的值都由 1 和 2 变成了 2 和 1,(1)直接改变指针的值,(2)改变指针所指变量的值,p1,b,2,&,b,p2,*,p2,a,1,&,a,*,p1,a,p1,b,2,&,a,p2,*,p1,1,&,b,*,p2,p1,b,1,&,b,p2,*,p2,a,2,&,a,*,p1,8.2,指针作为函数参数,一个关于发生在北宋年间变量替换的故事,关键点分析,真宗和李玉未出生的孩子:小王子,刘娥的阴谋:用狸猫替换掉孩子,筹备工作:设计两套替换行动方案,实施结果:行动一失败,行动二成功,int,main(void),int,baby=,PRINCE;,/*,baby,代表孩子,刚出生时是王子,*/,printf(before,change,baby is);,display,(baby);,replace1,(baby);/*,实施狸猫换太子第一次行动,*/,printf(n,);,printf(after,first action,baby is);,display,(,baby);,replace2,(/*,实施狸猫换太子第二次行动,*/,printf(n,);,printf(after,second action,baby is);,display,(baby);,return 0;,例8-6 指针作为函数参数模拟狸猫换太子,#define,CIVET,0,定义狸猫值为,0,#,define,PRINCE,1,定义王子值为,1,void,replace1,(int baby),baby=CIVET;,void,replace2,(int*baby),*baby=CIVET;,void,display,(int,who),if(who=CIVET),printf,(,狸猫,);,else if(who=PRINCE),printf,(,王子,);,before change,baby is,王子,after first action,baby is,王子,after second action,baby is,狸猫,8.2.2,指针,作为函数的参数,函数参数包括实参和形参,两者的类型要一致,可以是指针类型。,如果,实参,是某个变量的,地址,,相应的,形参,就是,指针,。,调用哪个函数,可以交换,main(),中变量,a,和,b,的值?,8.2.2,指针,作为函数的参数,int,main(void),int,a=5,b=9;,int,*pa=&a,*,pb,=,void swap1(int x,int,y),swap2(,int,*,px,int,*,py,),swap3(,int,*,px,int,*,py,);,swap1(a,b);,printf,(“After calling swap1:a=%d b=%dn”,a,b);,a=5;b=9;,swap2(pa,pb,);,printf,(“After calling swap2:a=%d b=%dn”,a,b);,a=5;b=9;,swap3(pa,pb,);,printf,(“After calling swap3:a=%d b=%dn”,a,b);,return 0;,调用哪个函数,可以交换,main(),中变量,a,和,b,的值?,例8-7,swap1(),swap1(a,b);,void swap1(,int,x,int,y),int,t;,t=x;,x=y;,y=t;,.,.,2000,2008,200A,2002,2004,2006,5,变量,a,变量,b,(main),9,变量,t,变量,y,变量,x,(swap1),5,5,9,5,9,COPY,输入:,5,,,9,运行结果:,5,9,例8-7,swap2(),swap2(,void swap2(,int,*,px,int,*,py,),int,t;,t=*,px,;,*,px,=*,py,;,*,py,=t;,值传递,地,址未变,,但存放的变量的值改变了,.,2000,2008,200A,2002,2004,2006,200C,200E,2010,.,5,9,整型变量,a,整型变量,b,(main),指针,pa,指针,pb,2000,2002,(swap),指针,px,指针,py,整型,t,5,9,5,例8-7,swap3(),swap3(,void swap3(,int,*,px,int,*,py,),int,*pt;,pt=,px,;,px,=,py,;,py,=pt;,值传递,形参指针的改变不会影响实参,.,2000,2008,200A,2002,2004,2006,200C,200E,2010,.,2000,2002,5,9,整型变量,a,整型变量,b,(main),pa,pb,2000,2002,(swap),指针,px,指针,py,指针,pt,2000,2002,2000,输入:,5,,,9,运行结果:,5,9,指针,作为函数参数的应用,swap2(,void swap2(,int,*,px,int,*,py,),int,t;,t=*,px,;,*,px,=*,py,;,*,py,=t;,要通过函数调用来改变主调函数中某个变量的值:,(1)在主调函数中,,将该变量的地址或者指向该变量的指针作为实参,(2)在被调函数中,,用指针类型形参接受该变量的地址,(3)在被调函数中,改变形参所指向变量的值,a,b,px,py,5,9,9,5,After calling swap1:a=5,b=9,After calling swap2:a=9,b=5,After calling swap3:a=5,b=9,通过指针实现函数调用返回多个值,例8-8 输入年和天数,输出对应的年、月、日。,例如:输入2000和61,输出2000-3-1。,定义函数,month_day(year,yearday,*,pmonth,*,pday,),用2个指针作为函数的参数,带回2个结果,int,main(void),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,printf,(%,d-%d-%d,n,year,month,day);,return 0;,例8-8,void 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*/,leap=(year%4=0,for(k=1;,yearday,tableapk;k+),yearday,-=tab,leapk,;,*,pmonth,=k;,*,pday,=,yearday,;,input year and,yearday,:,2000 61,2000-3-1,month,day,pmonth,pday,3,1,8.3,冒泡排序,-,程序解析,void,swap2,(,int,*,int,*);,void,bubble,(,int,a,int,n);,int,main(void),int,n,a8;,int,i;,printf(Enter,n(n=8):);,scanf(%d,printf(Enter,a%d:,n);,for(i=0;in;i+),scanf(%d,&ai,);,bubble,(a,n);,printf(After,sorted,a%d=,n);,for(i=0;in;i+),printf(%3d,ai);,return 0;,void,bubble,(,int,a,int,n),int,i,j;,for(i=1;i n;i+),for(j=0;j aj+1),swap2,(,void,swap2,(int*px,int*py),int,t;,t=*,px,;*,px,=*,py,;*,py,=t;,Enter n(n=8):,8,Enter a8:,7 3 66 3-5 22-77 2,After sorted,a8=-77-5 2 3 3 7 22 66,8.3.2,数组和地址间的关系,int,a100,*p;,数组名代表一个地址,它的值是数组首元素的地址(基地址),a+i,是距数组,a,的基地址的第,i,个偏移,3000 a0,地址 内容 数组元素,3002 a1,3198 a99,ai,a,a+1,a+99,a+i,&,ai,*,(,a+i),sum=0;,for(i=0;i 100;i+),sum=sum+ai ;,*(,a+i),下标运算符 的含义,指针和数组的关系,任何由数组下标来实现的操作都能用指针来完成,int,a100,*p;,p=a;,或,p=,p,p,+1,p,+99,p,+i,3000 a0,地址 内容 数组元素,3002 a1,3198 a99,ai,a,a+1,a+99,a+i,&ai,ai,a+i,*(a+i),p+i,*(p+i),&pi,pi,p=a;,sum=0;,for(i=0;i 100;i+),sum=sum+pi;,等价,等价,用指针完成对数组的操作,int,a100,*p;,移动指针,p,3000 a0,地址 内容 数组元素,3002 a1,3198 a99,ai,a,a+1,a+99,a+i,sum=0;,for(p=a;p=,p+),sum=sum+*p;,p,p,p,#include,int,main(void),double a2,*p,*q;,p=,q=p+1;,printf,(%dn,q-p,);,printf,(%dn,(,int,)q-(,int,)p,);,return 0;,例,8-10,使用指针计算数组元素个数和数组元素的存储单元数,1,8,指针,p,和,q,之间元素的个数,指针,p,和,q,之间的字节数,地址值,p,q,3000 a0,地址 内容 数组元素,3008 a1,a,a+1,double *p,*q;,q-p,两个相同类型的指针相减,表示它们之间相隔的存储单元的数目,p+1/p-1,指向下一个存储单元,/,指向上一个存储单元,其他操作都是非法的,指针相加、相乘和相除,或指针加上和减去一个浮点数,p q,两个相同类型指针可以用关系运算符比较大小,指针的算术运算和比较运算,p,q,3000 a0,地址 内容 数组元素,3008 a1,a,a+1,#include,int,main(void),int,i,a10,*p;,long sum=0;,printf(Enter,10 integers:);,for(i=0;i 10;i+),scanf(%d,for(p=a;p=a+9;p+),sum=sum+*p;,printf(sum,=%ld n,sum);,return 0;,例,8-11,使用指针计算数组元素之和,Enter 10 integers:,10 9 8 7 6 5 4 3 2 1,sum=55,p,3000 a0,地址 内容 数组元素,3002 a1,3018 a9,ai,a,a+1,a+9,a+i,p,p,p,数组元素作为函数实参时,函数形参为变量与变量作为函数实参相同,值传递,8.3.3,数组名作为函数的参数,double fact(,int,n);,int,main(void),int,i,n=5;,double sum;,sum=0;,for(i=1;i=n;i+),sum=sum+,fact(i);,printf(sum,=%en,sum);,return 0;,double fact(,int,n),int,i;,double result=1;,for(i=1;i=n;i+),result=result*i;,return result;,int,a5=1,4,5,7,9;,fact(ai-1);,1!+4!+5!+7!+9!,数组名是指针常量,相当于指针作为函数的参数,数组名,做为实参,形参是,指针变量,(数组),数组名作为函数的参数,int,sum(,int,*,array,int,n),int,i,s=0;,for(i=0;in;i+),s+=arrayi;,return(s);,例,8-12,int,main(void),int,i;,int,b5=1,4,5,7,9;,printf(%dn,sum(,b,5);,return 0;,(1)实参是数组名,(2)形参是指针变量,可以写成数组形式,int,array,*(,array+i),int,sum(,int,*array,int,n),int,i,s=0;,for(i=0;in;i+),s+=arrayi;,return(s);,int,main(void),int,i;,int,b5=1,4,5,7,9;,printf(%dn,sum(,b,5);,return 0;,b,b0,b5,array,sum(,b,5),b0+b1+.+b4,sum(,b,3),b0+b1+b2,sum(,b+1,3),b1+b2+b3,sum(,&,b2,3),b2+b3+b4,#include,int,main(void),int,i,a10,n;,void,reverse(int,p,int,n);,printf(Enter,n:);,scanf(%d,printf(Enter,%d integers:,n);,for(i=0;i n;i+),scanf(%d,reverse,(,a,n);,for(i=0;i n;i+),printf(%dt,ai);,return 0;,例,8-13,将数组元素逆序存放,void,reverse(int,p,int,n),int,i,j,t;,for(i=0,j=n-1;ij;i+,j-),t=pi;pi=pj;pj=t;,Enter n:,10,Enter 10 integers:,10 9 8 7 6 5 4 3 2 1,1 2 3 4 5 6 7 8 9 10,数组名做为函数的参数,在函数调用时,将实参数组首元素的地址传给形参(指针变量),因此,形参也指向实参数组的首元素。如果改变形参所指向单元的值,就是改变实参数组首元素的值。,或:形参数组和实参数组共用同一段存贮空间,如果形参数组中元素的值发生变化,实参数组中元素的值也同时发生变化。,a,a0,a5,p,指针实现,a0 p,数组元素 内容 指针,a1,a9,pj,#include,int,main(void),int,i,a10,n;,void,reverse(int,p,int,n);,printf(Enter,n:);,scanf(%d,printf(Enter,%d integers:,n);,for(i=0;i n;i+),scanf(%d,reverse,(,a,n);,for(i=0;i n;i+),printf(%dt,ai);,return 0;,void,reverse(int,*,p,int,n),int,*,pj,t;,for(pj,=p+n-1;paj+1,j=0 to 4,j=0 to 3,j=0 to 2,j=0 to 6-1-i,9 8 8 8 8 8 5 4 4 0,8 9 5 5 5 5 4 5 0 4,5 5 9 4 4 4 6 0 5,4 4 4 9 6 6 0 6,6 6 6 6 9 0 8,0 0 0 0 0 9,9 8 5 4 6 0,i=1,j=0:8 9 5 4 6 0,j=1:8 5 9 4 6 0,j=2:8 5 4 9 6 0,j=3:8 5 4 6 9 0,j=4:8 5 4 6 0 9,int,main(void),int,i,j,n,t,a10;,n=6;,for(i=0;i n;i+),scanf(%d,for(i=1;i n;i+),for(j=0;j aj+1),t=aj;,aj=aj+1;,aj+1=t;,return 0;,int,main(void),int,i,a10;,for(i=0;i10;i+),scanf(%d,sort(,a,10);,for(i=0;i10;i+),printf(%d,ai);,printf(n,);,return 0;,void,sort(int,*,array,int,n),int,i,j,t;,for(i=1;in;i+),for(j=0;jarrayj+1),t=arrayj;,arrayj=arrayj+1;,arrayj+1=t;,字符串:字符数组,字符指针,8.4.1,程序解析,8.4.2,字符数组和字符指针,8.4.3,常用的字符串处理函数,8.4,加密问题,8.4.1,程序解析加密,#define MAXLINE 100,void,encrypt(char,*s);,int,main(void),char line MAXLINE;,printf,(Input the string:);,gets(line,);,encrypt,(line);,printf,(“After being encrypted:%,sn,line);,return 0;,void,encrypt,(char*s),for(;*s!=0;s+),if(*s=z),*s=a;,else,*s=*s+1;,Input the string,:,hello,hangzhou,After being encrypted:,ifmmp!ibohaipv,8.4.2,字符串和字符指针,字符串常量,array,point,用一对双引号括起来的字符序列,被看做一个特殊的一维字符数组,在内存中连续存放,实质上是一个指向该字符串首字符的指针常量,char,sa,=array;,char*sp=point;,char,sa,=array;,char*sp=point;,printf(%s,sa,);,printf(%s,sp);,printf(%sn,string);,array point string,printf(%s,sa+2);,printf(%s,sp+3);,printf(%sn,string+1);,ray,nt,tring,数组名,sa,、指针,sp,和字符串,string,的值都是,地址,字符数组与字符指针的重要区别,char,sa,=This is a string;,char*sp=This is a string;,sa,T,h,i,s,i,s,a,s,t,r,i,n,g,0,sp,T,h,i,s,i,s,a,s,t,r,i,n,g,0,如果要改变数组,sa,所代表的字符串,只能改变数组元素的内容,如果要改变指针,sp,所代表的字符串,通常直接改变指针的值,让它指向新的字符串,示例,char,sa,=This is a string;,char*sp=This is a string;,strcpy,(,sa,Hello);,sp=Hello;,sa,=“Hello”;,非法,数组名是常量,不能对它赋值,字符指针先赋值,后引用,定义字符指针后,如果没有对它赋值,指针的值,不确定。,char*s;,scanf(“%s,”,s);,char*s,str20;,s=,str,;,scanf(“%s,”,s);,定义指针时,先将它的初值置为空,char*s=NULL,不要引用未赋值的指针,加密函数的两种实现,void,encrypt,(char,s,),int,i;,for(i=0;si!=0;i+),if(si=z),si,=a;,else,si,=si+1;,void,encrypt,(char,*s,),for(;*s!=0;s+),if(*s=z),*s=a;,else,*s=*s+1;,8.4.3,常用的字符串处理函数,函数原型在,stdio.h,或,string.h,中给出,1、字符串的输入和输出,输入字符串:,scanf,(),或,gets,(),输出字符串:,printf,(),或,puts,(),stdio.h,char str80;,i=0;,while,(stri,=,getchar,(),!=n),i+;,stri,=0;,(1),scanf(%s,str,),输入参数:字符数组名,不加地址符,遇,回车或空格,输入结束,并自动将输入的一串字符和,0,送入数组中,(2),gets(str,),遇,回车,输入结束,自动将输入的一串字符和,0,送入数组中,字符串的输入,n,t,char str80;,for(i=0;,stri,!=0;i+),putchar(stri,);,(3),printf(%s,str,),printf(%s,hello);,(4),puts(str,),puts(hello,);,输出字符串后自动换行,输出参数可以是字符数组名或字符串常量,输出遇,0,结束,字符串的输出,#include,int,main(),char str80;,scanf(%s,str,);,printf(%s,str,);,printf(%s,Hello);,return 0;,例,8-15,字符串输入输出函数示例,#include,int,main(),char str80;,gets(str,);,puts(str,);,puts(Hello);,return 0;,Programming,ProgrammingHello,Programming is fun!,ProgrammingHello,Programming,Programming,Hello,Programming is fun!,Programming is fun!,Hello,2、字符串的复制、连接、比较、求字符串长度,字符串复制:,strcpy(str1,str2),字符串连接:,strcat(str1,str2),字符串比较:,strcmp(str1,str2),求字符串长度:,strlen(str,),string.h,strcpy(str1,str2);,将字符串,str2,复制到,str1,中,static char str120;,static char str220=“happy”;,字符串复制函数,strcpy,(),h a p p y 0,0,strcpy(str1,str2);,h a p p y 0,str1,中,strcpy(str1,“world”);,str1,中:,w o r l d 0,#,include“,stdio.h,”,#include“string.h”,int,main(void),char str120,str220;,gets(str2);,strcpy(str1,str2);,puts(str1);,return 0;,strcpy,(),示例,1234,1234,strcat(str1,str2);,连接两个字符串,str1,和,str2,并将结果放入,str1,中,字符串连接函数,strcat,#,include,stdio.h,#include string.h,int,main(void),char str180,str220;,gets(str1);,gets(str2);,strcat(str1,str2);,puts(str1);,return 0;,str1,中:,Let us 0,str2,中:,go.0,str1,中:,Let us go.0,str2,中:,go.0,Let us,go.,Let us go.,strcmp(str1,str2),比较 两个字符串,str1,和,str2,的大小。,规则:按字典序(,ASCII,码序),如果,str1,和,str2,相等,返回 0;,如果,str1,大于,str2,,返回一个正整数;,如果,str1,小于,str2,,返回一个负整数;,static char s120=sea;,字符串比较函数,strcmp,strcmp(s1,Sea);,strcmp(Sea,Sea);,strcmp(Sea,Sea);,正整数,负整数,0,#,include“,stdio.h,”,#include“string.h”,int,main(void),int,res;,char s120,s220;,gets(s1);,gets(s2);,res=strcmp(s1,s2);,printf(“%d,”,res);,return 0;,strcmp,(),示例,1234,5,-4,利用字符串比较函数比较字符串的大小,strcmp(str1,str2);,为什么定义这样的函数?,用,strcmp,(),比较字符串,strcmp(str1,str2)0,strcmp(str1,“hello”)str2,str1 s1,strcat(s1,s2)s1“,+,”s2=s1,若,s1“,=,”s2,,函数值为0,strcmp(s1,s2),若,s1“,”s2,,函数值 0,string.h,若,s1“,”s2,,函数值0,计算字符串的有效长度,,strlen(str,),不包括 0,字符串处理函数小结,int,main(),int,i;,int,x,min;,scanf(%d,min=x;,for(i,=1;i 5;i+),scanf(%d,if(x,min),min=x;,printf(min,is%dn,min);,return 0;,例,8-16,求最小字符串,#include,int,main(),int,i;,char sx80,smin80;,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,);,return 0;,2 8-1 99 0,min is 1,tool key about zoo sea,min is about,8.5,任意个整数求和问题*,例,8-17 先输入一个正整数,n,,再输入任意,n,个整数,计算并输出这,n,个整数的和。,要求使用,动态内存分配方法,为这,n,个整数分配空间。,8.5.1 程序解析,int,main(),int,n,sum,i,*p;,printf(Enter,n:);,scanf(%d,if,(p=(,int,*),calloc,(n,sizeof(int,),=NULL),printf(Not,able to allocate memory.n);,exit(1);,printf(Enter,%d integers:,n);,for(i=0;i n;i+),scanf(%d,p+i);,sum=0;,for(i=0;i n;i+),sum=sum+*(p+i);,printf(The,sum is%d n,sum);,free(p,);,return 0;,Enter n:,10,Enter 10 integers:,3 7 12 54 2 19 8 1 0 15,The sum is 81,8.5.2,用指针实现内存动态分配,变量在使用前必须被定义且安排好存储空间,全局变量,、,静态局部变量,的存储是在,编译时,确定,在程序开始执行前完成。,自动变量,,在执行进入变量定义所在的复合语句时为它们分配存储,变量的大小也是静态确定的。,一般情况下,运行中的很多存储要求在写程序时无法确定。,动态存储管理,不是由编译系统分配的,而是由用户在程序中通过动态分配获取。,使用动态内存分配能有效地使用内存,使用时申请,用完就释放,同一段内存可以有不同的用途,动态内存分配的步骤,(,1,)了解需要多少内存空间,(,2,)利用,C,语言提供的动态分配函数来分配
展开阅读全文