《[其它]四川大学c程序课件第8章.ppt》由会员分享,可在线阅读,更多相关《[其它]四川大学c程序课件第8章.ppt(39页珍藏版)》请在三一办公上搜索。
1、第8章指针,Company Logo,主要内容,8.2 指针变量的定义,计算机基础 教学实验中心,Company Logo,8.1指针概述及定义,计算机基础 教学实验中心,Company Logo,8.2 指针变量的定义,对指针变量的定义包括三个内容:(1)指针类型说明,即定义变量为一个指针变量;(2)指针变量名;(3)变量值(指针)所指向的变量的数据类型。其一般形式为:类型说明符*变量名;这里的*并不是乘法运算符,而表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示该指针变量所指向的变量的数据类型。,计算机基础 教学实验中心,Company Logo,8.3 指针变量的引用,计
2、算机基础 教学实验中心,指针变量的引用即使用,使用之前必须赋予确定的值。若使用未经赋值的指针变量将造成系统混乱,甚至导致系统崩溃。,Company Logo,计算机基础 教学实验中心,&取地址运算符形式:&变量名&是单目运算符,其结合性为自右至左,优先级仅低于括号等一级优先的运算符。,8.3 指针变量的引用,Company Logo,指针定义注意事项,计算机基础 教学实验中心,1、在初始化时,必须先定义变量x,再将该变量的地址用取地址运算符赋给指针变量p,而不能颠倒其先后顺序,如以下定义便是错误的:int*p=被赋值的指针变量前不能再加“*”说明符,如写为*p=&a 也是错误的。,Compan
3、y Logo,指针定义例子,计算机基础 教学实验中心,例8.1 指出以下语句中的错误(0)#define M 99(1)float x,y,*pf;(2)char c,*pc;(3)int a10,*pi1,*pi2;(4)pf=(10)pf=&(x+y),Company Logo,*指针运算符,计算机基础 教学实验中心,取内容运算符*是单目运算符,其结合性为自右至左,用来表示指针变量所指的变量。在*运算符之后跟的变量必须是指针变量 例main()char c,*poniter=/*语句5*/该程序运行的结果为:bb,Company Logo,指针举例,计算机基础 教学实验中心,例8.3mai
4、n()int a,b,c,d,*p1,*p2;/*语句1*/p1=/*语句7*/,Company Logo,指针举例,计算机基础 教学实验中心,例 8.4 以下程序运行后,x,y,z的值各为多少?main()(1)int x,y,z,l=4,m=6,n=8;(2)int*p1=该程序的运行结果是:x=1y=9z=24,Company Logo,8.4 指针作为函数参数,计算机基础 教学实验中心,函数参数的类型,可是整型、实型、字符型等基本类型,也可以是指针类型 例85#inchlude main()int*p,*q;int m=58;int n=99;void change1();void c
5、hange2();void change3();p=m:q=n;*比较附试change1函数前后m,n的值*printf(“n调用change1函数之前:m=d n=%d”,m,n);changel(m,n);printf(“n调用change1函数之后:m=d n=%d”,m,n);*比较调试change2函数前后m,n的值*printf(“n调用change2函数之前:m=d n=%d”,m,n);,Company Logo,例85(continue),change2(mn);printf(“n调用change2函数之后:m=d n=%d”,m,n);*比较调试change3函数前后m,n
6、的值*printf(“m调用change3函数之前:m=d n=%d”,m,n);change3(p,q);printf(“n调用ehg3函数之后:m=d n=%d”,m,n);Void changel(int m,int n)m=1n=1printf(“n在函数change1中:m=%d n=%d”,m,n);,计算机基础 教学实验中心,Void change2(int*pm,int*pn)*pm=1;*pn=l:printf(“n在函数change2中:*pm=%d*pn=%d”,*pm,*pn);Void change3(int*pm,int*pn)int i;int j;i=2;j=2
7、;pm=,Company Logo,上面这段程序包含三个函数运行情况如下:调用change1函数之前:m=58 n=99 在函数change1中:m=1 n=1 调用change1函数之后:m:58 n=99 调用change2函数之前:m=58 n=99 在函数change2中:*pm=1*pn=1 调用change2函数之后:m=1 n=1 调用ck3函数之前:m=1 n=1 在函数change3中:*pm=2*pn=2 调用change3函数之后:m=1 n=1,计算机基础 教学实验中心,Company Logo,8.5指针数组,计算机基础 教学实验中心,8.5.1指向数组元素的指针变量
8、指向数组的指针变量的定义形式:int x100,y;int*p;整型变量y,整型数组x,指向整型的指针变量p。指针变量p并没有指向任何变量,它既可以指向整型的变量,如y,也可指向整型的数组x,这取决于把哪个变量的地址赋给p让p指向数组x可以写为:p=x;或p=x0;,Company Logo,8.5.2利用指针访问数组元素,当指针变量指向某个数组,在访问数组时就有两种方式:下标法和指针法。如:int*p,m20;p=m;指针法访问数组是用指向数组的指针变量加上某个数组元素的序号,得到该数组元素的地址后作指针运算*,即可表示该数组元素,如p+i为mi的地址,而*(p+i)就代表mi。指向数组的指
9、针变量也可带下标,如pi,即pi*(p+1)mi*(m+i),代表等价。,计算机基础 教学实验中心,Company Logo,例8.6用指针法和下标法访问数组,#include main()static int m10=0,1,2,3,4,5,6,7,8,9;int i;int*p;p=m;for(i=0;i=9;i+)printf(ni=%d,mi=%d,*(m+i)=%d,pi=%d,*(p+i)=%d,i,mi,*(m+i),pi,*(p+i);printf(,计算机基础 教学实验中心,Company Logo,8.5.4数组名及指向数组的指针变量作函数参数,在函数中,数组名可以作函数的
10、参数 当数组名作函数的参数时,由于数组名代表该数组的首地址即在调用函数时,将该数组的首地址传给形参,形参和实参共同指向一段内存,形参并未开辟新的存储单元,计算机基础 教学实验中心,Company Logo,例 二分查找算法,用binary search(二分查找算法)从一个已排好序的数列中查找一个数,判定此数是否属于该数列。int b_search(m,num,key)int m,num,key;int l,h,mid;l=0;h=num-1;while(lmmid)l=mid+1;else return(mid);return(-1);,计算机基础 教学实验中心,Company Logo,例
11、二分查找算法,main()static int b=10,12,13,14,25,34,72,88,100;int k,i,j;printf(The arranged array is:n);for(i=0;i9;i+)printf(%d,bi);printf(n);printf(Please input the key number which is to be searched:n);scanf(%d,计算机基础 教学实验中心,Company Logo,8.5.4数组名及指向数组的指针变量作函数参数,计算机基础 教学实验中心,对这个程序可以作一些改动,将bin_search函数中的形参m用
12、指针代替,实参为数组名b,传给形参指针变量,使形参指向数组b的首地址。int bin_search(m,num,key)int*m,num,key;int1,h,mid;1=0;h=num-1while(1*(m+mid)1=mid+h;elsereturn mid;/*找到了*/return-1;,Company Logo,例8.9,计算机基础 教学实验中心,阅读下列程序,在编号(1)、(2)、(3)、(4)处分别填入合适的语句,使程序完整。说明:下面的程序用invert函数按逆序重新放置a数组中元素,a数组的值由用户用健盘输入。#include#define LEN 10main()int
13、 aLEN,i;void invert();for(i=0;iLEN;i+)(1)(“%d”,Company Logo,例8.9,void invert(x,m,n)int*x,m,n;int k;if(mn)k=(3);*(x+m)=*(x+n);*(x+n)=k;invert(x,(4),n-1);,计算机基础 教学实验中心,Company Logo,例8.9,分析:该程序的目的是:用户从键盘上输入LEN个数(10个数),存在a数组中。然后调用invert函数,把数组a中的元素首尾依次对调,如图8.14所示:a0与a9对调,a1与a8对调,直到全部元素对调为止。在main函数中,通过键盘输
14、入数组的值,这里笫(1)个空就应该填上scanf。main函数中调用invert函数,以便将a数组首尾颠倒,invert函数的形参为指向整型变量的指针x,把数组a的地址传给它,使x指向a,所以(2)应为a。在invert函数中,形参x指向数组a,m和n分别指向需要交换的二个数组元素的下标当n、n为止,如图所示,所以第4个空应该填m+1。,计算机基础 教学实验中心,Company Logo,8.6指针运算,1指针变量的赋值运算 指针变量定义之后,并不能象其他变量那样随意对它赋值。char c1,*q;定义q为指向字符型变量的指针,表明q可以存放某个字符型变量的地址,但如果用下列语句给q赋一个地址
15、值:q=2000;则是不可以的 赋值的形式有如下几种:,计算机基础 教学实验中心,Company Logo,(1)利用取地址运算符,计算机基础 教学实验中心,Company Logo,(2)同类型的指针变量可以进行赋值运算,其结果是二者同时指向一个变量,如:float m,*p1,*p2;p1=&m;p2=p1;这里*p1,*p2与m的值相等,计算机基础 教学实验中心,Company Logo,(3)利用强制类型转换运算可以实现不同类型指针的相互赋值 如果在不同类型的指针间进行相互赋值,往往会导致编译时出现错误。有时若一定要使不同类型的指针变量进行交叉赋值,则必须用强制运算符,如:char c
16、l,*p1;double x,*p2;如果一定要用pl指向x,则必须这样写:p1=(char*)(char*)&x实现强制类型转换,把变量x的地址强制换成char类型数据的地址,这样两边的类型一致了,就可以进行赋值运算。,计算机基础 教学实验中心,Company Logo,(4)对字符指针变量赋初值可采用字符串赋值的形式,如:char*m;m=“This is a pen”;使m指向“This is a pen”字符串,m此时的值为该字符串第零个元素的地址,即T这个字符存放在内存中的地址。,计算机基础 教学实验中心,Company Logo,8.6.2 指针变量的*运算-间接引用对指针变量的间
17、接引用是通过用间接运算符*来实现的,由于*(间接运算符)级别仅次于括号,所以对指针变量的间接引用往往可作为一个整体来分析。如:main()int k=2,*pk=由于*pk等价于k,*pm等价于m.所以,*pk*(*pm)即为k*m,(24)值为8。,计算机基础 教学实验中心,Company Logo,例8.13 分析以下程序执行后的结果。(1)#include stdio.h(2)main()(3)(4)static int m5=7,4,6,3,10;(5)int i,j,*p;(6)i=10;(7)p=(11),计算机基础 教学实验中心,Company Logo,8.6.3、指针的加减运
18、算对指针变量进行加上或减去一个整数称为移动指针,使指针变量指向相邻的存储单元。只有当指针指向一段连续的内存单元时,指针的移动才有意义。除了上述加减运算外,指针变量不能作其他任何的算术运算,如指针变量的乘除,取模运算等。,计算机基础 教学实验中心,Company Logo,8.7 指向字符串的指针,通常用字符数组表示字符串,如:char s=“This is a book”;若用字符指针来表示,则应写为:char*p=“This is a book”;或者:char*p;p=“This is a book”,计算机基础 教学实验中心,Company Logo,8.7 指向字符串的指针,例:(1)
19、#include(2)#include(3)main()(4)(5)char s=“Sichuan University”;(6)char*p;(7)int*q;(8)int a 10=1,2,3,4,5,6,7,8,9,10;(9)p=“Sichuan University”;(10)q=a;(11)printf(“%s,%s”,p,s);(12)printf(“%s,%s”,q,a);(13)在上述程序中,第(11)条语句输出如下结果:Sichuan University,Sichuan University而第(12)条语句则会出错,因为通过字符数组名或字符指针变量可以输出整个字符数组名
20、或字符串,如语句(11),而对于数值型数组,是不能这样做的,如第(12)条语句就是错误的。,计算机基础 教学实验中心,Company Logo,8.7 指向字符串的指针,字符指针变量和字符数组的区别:(1)字符指针变量中存放的是字符串的首地址,不是将字符串放到字符指针变量中,而字符数组则由若干数组元素组成,每个元素放一个字符。(2)赋初值的方式不同:对于字符指针char*s=“This is a pen”;等价于char*s;s=“This is a pen”;对于字符数组初始化:static char m30=“This is a pen”;不等价于static char m30;m=“Th
21、is is a pen”;因为数组可以在变量定义时整体赋初值,除此之外不能用赋值语句给其赋值。,计算机基础 教学实验中心,Company Logo,8.7 指向字符串的指针,(3)赋值方式不同对于字符数组,赋值方式是用赋值语句给其每一个元素赋值一个字符,而不能将整个字符串赋给它。若一定要在语句中将整个字符串赋给一个字符数组,则必须用strcpy函数来实现,如:char s30;s=“Sichuan university”;是错误的,应该用下方式进行赋值。s0=S;s1=i;s2=c;s17=y;或用:strcpy(s,“Sichuan university”);,计算机基础 教学实验中心,Co
22、mpany Logo,8.7 指向字符串的指针,char*s;s=“Sichuan university”;是正确的。字符指针之间的相互赋值与其它变量无异,如:char*s1=“Sichuan university”;char*s2;s2=s1;就可将s1的值赋给了s2。,计算机基础 教学实验中心,Company Logo,例8.15-,+与字符指针的综合应用,#include main()char s=sichuanuniversity;int*pc=s;printf(pc=%d*pc=%cn,pc,*pc);printf(pc=%d*pc=%cn,pc,+(*pc);printf(pc=%d*pc=%cn,pc,+*pc);printf(pc=%d*pc=%cn,pc,*pc);printf(pc=%d*pc=%cn,pc,*(+pc);printf(pc=%d*pc=%cn,pc,*+pc);printf(pc=%d*pc=%cn,pc,*pc-);printf(pc=%d*pc=%cn,pc,*pc+);程序运行结果如图。,计算机基础 教学实验中心,Company Logo,计算机基础 教学实验中心,例8.15,