第7章指针.ppt

上传人:本田雅阁 文档编号:3131731 上传时间:2019-07-14 格式:PPT 页数:94 大小:1.85MB
返回 下载 相关 举报
第7章指针.ppt_第1页
第1页 / 共94页
第7章指针.ppt_第2页
第2页 / 共94页
第7章指针.ppt_第3页
第3页 / 共94页
第7章指针.ppt_第4页
第4页 / 共94页
第7章指针.ppt_第5页
第5页 / 共94页
点击查看更多>>
资源描述

《第7章指针.ppt》由会员分享,可在线阅读,更多相关《第7章指针.ppt(94页珍藏版)》请在三一文库上搜索。

1、第7章 指针,C语言大学实用教程,西南财经大学经济信息工程学院 刘家芬 ,数据在内存中的存储,计算机的内存区由连续的内存单元构成,每个内存单元的大小是一个字节,每一个字节有一个编号,也就是常说的“地址“。 每一个变量在内存中都占据一定内存空间,空间的大小由变量的类型确定。整型变量在内存中占用2个字节,float型变量在内存中占用4个字节。 在程序中一般是通过变量名来对内存单元进行存取操作的。而实际上,编译过程中所有的变量名都会被转换为变量的地址,计算机对变量的值的存取,都是通过地址来进行的。,假设程序中定义了2个整型变量i和j,编译器在编译的时候,为变量i分配地址编号为2000和2001的两个

2、字节;而为变量j分配2002、2003的两个字节。 如果有语句 j=i+j,计算机在执行过程中将首先从地址2000、2001中取出其中的值(变量i的值),然后从地址2002、2003中再取出其中的值(变量j的值),然后将这两个值进行相加,将相加的结果保存在内存地址2002、2003中。 这种通过变量地址直接存取变量值的方式,称为“直接访问“方式。,除了“直接访问“方式外,还可以采用“间接访问“方式,来对一个变量的值进行存取: 将变量i的地址2000,存放在另一个变量i_pointer当中,访问的时候,通过取出i_pointer的值,找到变量i的地址2000,然后再从2000、2001中,取出变

3、量i的值。,2000,i_pointer,i,2000,这种间接访问,从变量i_pointer开始,最终也能访问到变量i的值。,由于通过地址能找到所需的变量,因此可以说地址指向该变量单元。在C语言中,将地址形象化地称作“指针”。,变量的值保存在内存单元中,该内存单元可以通过地址来标识。 变量的地址即存放数据的内存地址,就是该变量的指针。 指针可以保存在变量中,这种专门用来保存指针的变量,称为指针变量。 指针变量i_pointer中保存了变量i的地址2000。2000指向变量i,我们也可以说指针变量i_pointer指向变量i。,指针和地址的概念,变量的指针和指向变量的指针变量,变量的指针就是变

4、量的地址,而指针变量就是指存放地址型数据的变量。 为了表示指针变量和所指向的变量之间的联系,C语言中用*表示“指向”关系。 右图中(*i_pointer)就是指针变 量i_pointer所指向的变量,即i。 指针变量的定义 格式:基类型 * 指针变量名; 基类型是该指针变量指向的变量的类型。例如: float *p; (p是指向浮点型变量的指针变量) int *q; (q是指向整型变量的指针变量),2000,i_pointer,3,i,2000,*i_pointer,注意: 指针变量名前面的*表明该变量为指针变量,指针变量的名字是p、q,而不是*p、*q。 在定义指针变量时必须指定基类型。基类

5、型规定了指针类型变量所指向的变量的类型,一个指针变量只能指向同一类型的变量。 例如: float *p; 这里定义的指针类型变量p只能指向float型的变量,也就是说,它只能保存一个float型变量的地址,而不能保存其他类型变量(比如int型的变量)的地址。以下是错误的: int i; float *p=,定义了指针变量后,如何使其指向某个变量? 可以通过赋值语句使指针变量得到另一个变量的地址,从而使它指向另一个变量: int i=6; int *p; p= (这个赋值语句将整型变量i的地址赋给了指针变量p,从而使p指向了变量i),p,&i,i,6,指针变量的引用,指针变量只能存放地址,不能将

6、一个整数(或其他非地址类型的数据)赋给一个指针变量。例如下面是错误的: int *p=100; 两个有关的运算符: (1) ,#include void main() int a,b; int *p1,*p2; a=100;b=10; p1= ,例7.1,说明: 在开始定义了两个指针变量p1和p2,但是定义的时候,并没有给它们赋初值,这个时候,p1和p2并未指向任何变量。 “p1= 这里*p1和*p2分别代表p1和p2所指向的变量的内容。,有如下程序段: int a,*p; p= 问:(1) &*p的含义是什么? 分析:&和*这两个运算符的优先级相同,按照右结合,先进行*p的运算,它就是变量a

7、,然后再执行&运算,即&a运算,得到变量a的地址。 (2) *&a的含义是什么? 分析:和上面类似,&a运算是取变量a的地址,然后执行*运算,即&a所指向的变量,即是变量a。,输入a和b两个整数,按照先大后小的顺序输出a和b。 #include void main( ) int *p1,*p2,*p, a, b; scanf(“%d,%d“, ,例7.2,这个程序的算法思想是:使用p1和p2分别指向a和b。当a小于b的时候,交换p1和p2的内容,使得p1指向b,p2指向a。输出时,先输出p1指向的那个变量,后输出p2指向的那个变量。,p1,&a,a,5,&b,b,10,p2,p1,&b,a,5

8、,&a,b,10,p2,(1)开始时,(2)输出时,指针变量作为函数参数,指针变量也可以作为函数参数来传递信息 例7.3 输入两个整数,按照先大后小的顺序输出。,#include void main() void swap(int *p1,int *p2); int a,b, *point_1,*point_2; scanf(“%d,%d“, ,分析程序: 1.在main函数中,swap的实参是point_1,point_2。这两个指针变量分别保存了a和b的地址。 2.在swap被调用时,形参p1和p2分别被赋予实参point_1和point_2的值,因此,p1指向变量a,p2指向变量b 3.

9、swap函数的执行,使p1指向的变量(a)的内容和p2指向的变量(b)的内容进行了交换。 4.在main中按先a后b的顺序打印结果。这个时候,a中保存的值,大于b中保存的值的。,p1,&a,a,5,&a,point_1,p2,&b,b,9,&b,point_2,p1,&a,a,9,&a,point_1,p2,&b,b,5,&b,point_2,swap开始时,swap结束时,能否使用普通变量作函数参数,即 void swap(int x,int y) int temp; temp=x; x=y; y=temp; 并在main函数中调用swap: swap(a,b);,思考,答案:不行。因为a和

10、b的值在传递给swap的形参x和y后,不会改变(我们称为值传递): 若要使被调函数对某个变量的值的改变,在主调函数中可见,那么可以使用指针变量作函数参数。调用时,传递变量的地址给被调函数。,a,5,b,9,x,5,y,9,swap开始时,a,5,b,9,x,9,y,5,swap即将结束时,另一个解决方案,是否可行? #include void main() void swap(int *p1,int *p2); int a,b, *point_1,*point_2; scanf(“%d,%d“, ,编程者意图通过swap,交换main函数中的point_1和point_2的内容。但是这是不能实

11、现的,因为swap只能交换形参p1和p2的内容,而不能把这种影响反映到main中的point_1和point_2中去。,再一个解决方案,是否可行? #include void main() void swap(int *p1,int *p2); int a,b, *point_1,*point_2; scanf(“%d,%d“, ,*p是指针变量p所指向的变量,而p指向哪里? 如果对*p赋值,可能造成系统崩溃!,数组和指针,数组也要占用内存。数组占用一个连续的内存区域,数组中元素在内存中的存储位置是相邻的。例如:int a6; 假定数组a的首地址为2000:,a0,a1,a2,a3,a4,a5

12、,2000,2002,2004,2006,2008,2010,a,指向数组元素的指针,数组元素相当于变量,所以指向数组元素的指针,和指向变量的指针相同: int a10; int *p; p= ,通过指针引用数组元素,程序段:int a10; int *p= 的作用是? 将数组a中最后一个元素a9赋值为100,C语言规定:如果指针变量p已经指向数组中的一个元素,则p+1指向同一个数组中的下一个元素。例如: int a10; int *p=) 这里p+1不是简单的对地址数值进行加1。假设数组a的首地址为2000,p初始值为2000,p+1的值为2002,因为int型的变量在内存中占两个字节,p+

13、1为2002,指向元素a1 若p指向数组中第一个元素a0,p+i和a+i就是ai的地址,指向数组元素ai;*(p+i)和*(a+i)就代表数组元素ai。,注意:指向数组的指针变量也可以带下标,如pi与*(p+i)等价 数组名也是一个指针变量,它指向数组的首地址。因此: int a10; *(a+5)=100;等价于a5=100;,(1)使用下标法访问 #include void main() int a10; int i; for(i=0;i10;i+) scanf(“%d“, ,例7.4 输出数组中全部元素,(2) 使用数组名计算数组元素地址,找出元素的值 #include void mai

14、n() int a10; int i; for(i=0;i10;i+) scanf(“%d“, ,(3) 使用指针变量指向数组元素 #include void main() int a10; int i,*p; for(i=0;i10;i+) scanf(“%d“, ,注意:p作为指向数组元素的指针变量,可以通过改变指针变量的值指向不同的元素。可以进行p+操作,即p的值可以更改;数组名a虽然也作为指针,但是a的值不能修改,因此不能进行a+操作。,注意: 1. int a10; int *p=a; 则p+10指向的内存地址,已经超出了数组a的范围。如果程序中出现 *(p+10)=100; 已经超

15、出了数组a的边界。因为不确定(p+10)指向的内存区域用于何种目的,所以这样赋值可能会使系统崩溃。 2.比较*(p+) *(+p) +(*p),*p,然后p指向数组下一元素,p+使p指向数组下一元素,读取当前*p,使p指向的内存单元中的值加1,指针变量1-指针变量2 结果为:两个指针指向的数组元素间的距离 例:指向同一数组的指针变量相减 float x10,*p1=x+2,*p2= p1-p2 的值是- p2-p1 的值是 说明两个元素之间的距离是6,指向同一数组的指针变量之间的减法运算,用数组名作函数参数,第六章中已经讲过:用数组名作函数参数时,实际上传递的只是实参数组的首地址;在内存中只分

16、配了一个数组空间,而不是两个。被调函数中对形参数组的修改,在主调函数中可见。 在掌握了指针的概念之后,我们再来深入分析一下用数组名作函数参数。,void f(int arr ,int n) 实参数组名array代表该数组的首地址,形参用来接收从实参传递过来的首地址,因此形参应该是一个指针变量,因为只有指针变量能存放地址。 使用数组名作函数参数时,形参int arr 表示arr是数组名,C编译器会将形参数组名作为指针变量来处理。因此void f(int arr ,int n) 和void f(int *arr,int n) 是等价的,编译器会建立一个指针变量arr,用来存放从主调函数中传过来的实

17、参数组的首地址。,void main( ) int array10; f(array,10); ,实参数组名为array ,当调函数f时,形参arr接受array数组的首地址,因此arr也指向array数组。 根据前面讲的指向数组元素的指针所具有的性质,我们可以使用几种等价的方式来访问数组array中的元素。例如array1还可以用以下两种方式来表示:arr1、*(arr+1)。,arr,array,arr+1,数组名作函数参数时,C编译器将形参数组名作为指针变量来处理。传递给这个形参的值是实参数组的首地址。 注意: 1. 因为形参数组名被编译成指针变量,所以可以改变它的值。例如 “arr+;

18、“ 是允许的。 2. 而实参数组名array虽然也指向数组中第一个元素,但是array的值不能被修改,它是一个指针常量。例如 “array+;“ 是错误的。,例7.5 将数组a中的n个整数按相反顺序存放 #include void main() void inv(int x ,int n); int i, a10=3,7,9,1,0,6,7,5,4,2; printf(“The original array:n“); for(i=0;i10;i+) printf(“%d,“,ai); printf(“n“); inv(a,10); printf(“The array has been inve

19、rted:n“); for(i=0;i10;i+) printf(“%d,“,ai); printf(“n“); ,void inv(int x,int n) int temp,i,j,m=(n-1)/2; for(i=0; i=m; i+) j=n-1-i; temp=xi; xi=xj; xj=temp; ,i,m,j,算法:将a0与an-1互换,再将a1与an-2互换直到中间元素。用for循环处理,i和j分别指示需要对换的两个元素位置,初值为0和n-1,然后i+并且j-,直到i=(n-1)/2。 第一个形参x实际上是一个指针变量,x指向数组a的首元素。通过xi指向的实际上就是ai。 第二

20、个形参n用来接收需要进行处理的元素的个数。可以通过inv(a,5)表示对数组前5个元素进行颠倒。,注意:算法并不是唯一的!,对程序进行修改,将inv函数中的参数x改成指针: #include void main() void inv(int *x,int n); int i, a10=1,3,5,7,9,11,13,15,17,19; printf(“The original array:n“); for(i=0;i10;i+) printf(“%d,“,ai); printf(“n“); inv(a,10); printf(“The array has been inverted:n“);

21、for(i=0;i10;i+) printf(“%d,“,ai); printf(“n“); ,void inv(int *x,int n) int *p, temp,*i, *j, m=(n-1)/2; i=x;j=x+n-1;p=x+m; for(;i=p;i+,j-) temp=*i; *i=*j; *j=temp; 这个函数里采用了指向整型变量 的指针变量i和j,分别指向将要 交换的两个数组元素。,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a数组,i,x,p=x+m,j,归纳起来,如果有一个实参数组,要想在函数中改变此数组中的元素的值,实参和形参可分别为: 形参和实参

22、都用数组名 实参用数组名,形参用指针变量 实参形参都用指针变量 实参用指针变量,形参用数组名,#include void main() void inv(int *x,int n); int i, *a; printf(“The original array:n“); for(i=0;i10;i+) scanf(“%d“,a+i); printf(“n“); inv(a,10); printf(“The array has been inverted:n“); for(i=0;i10;i+) printf(“%d“,*(a+i); printf(“n“); ,这个main()有问题吗?,#in

23、clude void main() int a=5,*p1=这条语句,对这个未知内存空间的值进行改变,这是很危险的。如果这个地址存放的是系统关键程序内容,可能会使系统崩溃。 总结:在指针变量的值未被初始化时,没有指向某个变量,不要使用该指针变量!,例7.6选择法排序,void sort(int x,int n) int i, j, k, t; for(i=0;ixi) k=j; if(k!=i) t=ki;xi=xk;xk=t; ,多维数组与指针,回顾“一维数组与指针“小节所讲的内容: 1.数组名是个指针常量,它指向数组中的首元素。 2.若数组名为a,a+i指向数组中第i+1个元素ai;对数组

24、中第i个元素的访问,可以使用ai,也可以使用*(a+i)。,多维数组元素的地址,C语言把二维数组,作为一维数组来处理;这个一维数组的每个元素,又是一个一维数组。 例如int a34=1,3,5,7,9,11,13,15,17,19,21,23 数组a是一个二维数组。C语言把a被看作一个一维数组,它包含3个元素a0,a1,a2。 而每一个元素,又是一个一维数组。例如a0是一维数组名,a0这个一维数组包括了a00, a01, a02,a03这4个元素。,a0,a1,a2,1,3,5,7,9,11,13,15,17,19,21,23,=,=,=,a(2000),按照一维数组的知识: 数组名是个指针常

25、量,它指向数组中的第一个元素。可以得出:二维数组名a是个指针常量,它指向数组中第一个元素a0 (a0同时也是一个一维数组1, 3, 5, 7)。 同时,我们也可以得出:a=2000的话,a+1=2008,因为a+1指向a数组中第二个元素a1(每一行是一个一维数组,包含4个整型数,占用8字节) 因为a+1指向a数组中的第二个元素a1,因此可以用*(a+1)来表示第二个元素a1(a1是一维数组9,11,13,15),a0,a1,a2,1,3,5,7,9,11,13,15,17,19,21,23,=,=,=,a(2000),a0,a1,a2是3个一维数组。因此,a0作为一维数组的名字,代表数组1,3

26、,5,7的首地址,即&a00。同样,a1中的值是&a10,a2中的值是&a20。 考虑0行1列的元素地址如何表示? 答:a0+1。也可以用&a01来表示。a0的值为2000,a0+1的值为2002。 a0可以用*(a+0)来表示 因此0行1列的元素的地址a0+1也可以用*(a+0)+1来表示 i行j列的元素的地址为ai+j或*(a+i)+j 那么i行j列的元素的值,可以用*(*(a+i)+j)来表示。,在分析二维数组的时候,首先把二维数组看成一个一维数组,然后按照一维数组的方法来处理。 二维数组作为一维数组处理,其中的每一个元素,又是一个一维数组。对这些一维数组,也使用一维数组的方法来处理。,

27、指向多维数组元素的指针变量,(1)指向数组元素的指针变量 例7.7 用指针变量输出二维数组元素的值 include void main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for(p=a0;pa0+12;p+) if(p-a0)%4=0) printf(“n“); printf(“%4d“,*p); printf(“n“); ,分析: 因为p是指向int型变量的指针变量,每次p+操作,p指向下一个数组元素。 二维数组元素按行依次存放,先存第一行,然后存第二行,再存第三行,9,11,13,15,17,19,21,23,1,3,5,7

28、,p,p+1,注意:aij的地址是&a00+i*m+j。其中m是二维数组的第二维的大小,m=4,i=1,j=2,a12是a00后面第1*4+2个元素,指向一维数组的指针变量,分析下面几个定义的含义: int *p; (定义一个指针变量p,p指向一个整型变量) int a10;(定义一个长度为10的整型数组a。a是数组名,因此可以看作指针常量,a指向数组的首元素) int (*q)10; (定义一个指针变量q,它指向一个长度为10的整型数组) 以上定义的p和a,它们指向的内容是一个整型元素,占2个字节。但指针q,它指向的是一个数组,占2*10个字节。,例7.8 输出二维数组中任意一个元素 inc

29、lude void main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4,i,j; /*定义p为指针变量,指向包含4个元素的整型数组*/ p=a; for(i=0;i3;i+) for(j=0;j4;j+) printf(“%2d “,*(*(p+i)+j); printf(“n“); ,说明: “int (*p)4;” 表示p是一个指针变量,它指向包含4个整型元素的一维数组。这里如果不加括号int *p4,表示定义一个指针数组(后面会讲到),因此括号不能省略。 a是二维数组名,因此a指向数组中的第一个元素a0。a0是一个包含4个整型

30、元素的一维数组。因此,p=a这个赋值是合理的。,3. p+i是二维数组a的i行的起始地址,即元素ai的地址。 而*(p+i)表示的是二维数组的第i个元素ai,它即是包含4个整型元素的普通一维数组名。因此对应的第j个元素的地址可以用*(p+i)+j来表示,这个地址中存放的值就用*(*(p+i)+j)表示。,1,3,5,7,9,11,13,15,17,19,21,23,p,p+2,a0,a1,a2,用指向数组的指针作函数参数,一维数组名可以作函数参数,二维数组名也可以作函数参数。二维数组名,就是一个指向一维数组的指针。 例7.9 有一个班,3个学生,学习4门课程,计算总的平均分,以及第n个学生的成

31、绩。,#include void main() void average(float *p, int n); void search(float (*p)4, int n); float score34=65,67,70,60,80,87,90,81,90,99,100,98; average(*score,12);/*12个成绩的平均值*/ search(score,2);/*求序号为2的学生成绩*/ void average(float *p,int n) /*指向数组元素的指针p*/ float *p_end; float sum=0,aver; p_end=p+n-1; for(;p=

32、p_end;p+) sum=sum+(*p); aver=sum/n; printf(“average=%5.2f“,aver); ,void search(float (*p)4, int n) /*指向长度为4的一维数组的指针p*/ int i; printf(“the score of No.%d are:n“,n); for(i=0;i4;i+) printf(“%5.2f“,*(*(p+n)+i); ,字符串与指针,在C语言中,可以用两种方法访问一个字符串: 1. 用字符数组存放一个字符串,然后输出该字符串。例如: void main() char string=“I love ch

33、ina!“; printf(“%sn“,string); ,2. 用字符指针指向一个字符串。例如: void main() char *string=“I love China!“; printf(“%sn“,string); C编译器首先在内存中分配一个字符数组空间来保存字符串常量“I love China!”,然后,把这个字符串的第一个字符的地址,赋给指针变量string;不要误认为是把整个字符串“I love China!“赋给了变量string。 对一个字符串,可以通过首地址,使用%s来输出。,例7.10 将字符串a复制到字符串b void main() char a=“I am a

34、boy.“, b20; int i; for(i=0;*(a+i)!=0;i+) *(b+i)=*(a+i); *(b+i)=0; printf(“string a is:%sn“,a); printf(“string b is:“); for(i=0;bi!=0;i+) printf(“%c“,bi); printf(“n“); ,程序中,a和b都是数组名,因此*(a+i)表示的就是ai,*(b+i)表示的是bi。 输出一个字符串,可以使用%s输出,还可以通过%c依次输出每个字符。,字符指针作函数参数,例7.11用函数调用实现字符串的复制 (1)用字符数组作函数参数 void main()

35、void copy(char from,char to); char a=“I am a teacher“; char b=“You are a student“; copy(a,b); printf(“string b=%sn“, b); ,void copy(char from,char to) int i=0; while(fromi!=0) toi=fromi; i+; toi=0; ,(2)使用字符指针变量作形参 void main() void copy(char *from,char *to); char a=“I am a teacher“; char b=“You are a

36、 student“; char *x=a,*y=b; copy(x,y); /*使用copy(a,b);也可以*/ printf(“string b=%sn“,b); void copy(char *from,char *to) for(;*from!=0;form+,to+) *to=*from; *to=0; ,对字符指针变量和字符数组的说明 1.字符数组由若干个元素组成,每个元素存放一个字符。而字符指针变量用来存放一个地址。 2.字符指针变量可以通过赋值进行字符串的复制,但字符数组不行,只能通过字符串拷贝函数来复制。 char *p; char str14, a=“I am a boy“

37、; p=a;(正确) str=a; (错误),3. 对字符指针变量赋初值: char *p=“I am a boy“; 是将字符串“I am a boy”第一个元素的地址赋给p。 4. 指针变量的值是可以改变的。例 void main() char *a=“I love China“; a=a+7; printf(“%sn“,a); 输出结果:China,指向函数的指针,函数也要占用内存。一个函数在编译之后,会生成二进制代码,并且编译器会为这个函数分配一个地址空间,这个地址空间的起始地址(入口地址),就称为函数的指针。 可以用一个指针变量指向函数,然后通过这个指针变量来调用此函数。,回顾第一章

38、的例子: #include void main( ) int max(int x, int y); int a,b,c; scanf (“%d, %d“ , printf (“max= %d“ , c) ,int max( int x , int y) int z; if (xy) z=x; else z=y; return (z); ,改写这个例子中的主函数: #include void main( ) int max(int x, int y); int (*p)(int, int); /*定义指向函数的指针变量p*/ p=max;/*max是函数名,指向函数入口地址*/ int a,b,

39、c; scanf (“%d, %d“ , /*通过指针p来调用max*/ printf (“max= %d“ , c) ,分析: 1. int (*p)(int, int); 这条语句是定义一个指向函数的指针变量p,该函数具有两个整型参数,并且函数返回值为整型。 定义中(*p)的括号不能省略,如果省去括号 int *p(int, int); 代表声明一个函数p,它的返回值是一个指向整型变量的指针。,2. 与数组名指向数组首元素类似,函数名max也是一个地址常量,它保存该函数的起始地址。 p=max;这条赋值语句 使p指向函数max。 3. 要调用max函数,可以直接使用函数名: max(a,b

40、); 也可以通过指针p (*p)(a,b); 因此,程序里有语句: c=(*p)(a,b);,指令1,指令2,max p,指向函数的指针变量的定义的一般形式为: 数据类型 (*指针变量名)(函数参数表列) 例如: int (*p)(int, int); 指向函数的指针p,不能使用p+使p指向下一条指令。p+n或者p-n是无意义的。,指向函数的指针变量作函数参数,例7.12 设一个函数process,在调用它的时候,每次实现不同的功能。输入a和b两个数,第一次调用process时找出a和b中大的那个数,第二次找出其中小者,第三次求a与b之和。,#include void main() int m

41、ax(int,int); int min(int,int); int add(int,int); void process(int,int,int(*fun)(int,int); int a,b; scanf(“%d,%d“,void process(int x,int y,int (*fun)(int,int) int result; result=(*fun)(x,y); printf(“%dn“,result); ,说明: 在这个程序中,max,min,add分别是三个函数名,分别指向三个函数的起始位置。 main函数中3次调用了process,每一次的执行都不相同。因为process使

42、用了指向函数的指针作参数,3次执行,分别调用了max,min和add函数。 这种程序设计方法增加了设计的灵活性。在UNIX操作系统中,内核和驱动程序接口部分的代码,就大量使用了指向函数的指针变量作函数参数。,返回指针值的函数,一个函数可以返回整型值,字符型值,浮点型值,还可以返回指针型值。 返回指针值的函数的一般形式: 类型名 * 函数名(参数表列); 例如int *a(int x,int y); a是函数名,调用它之后,能得到一个指向整型数据的指针。x和y是函数a的形参。 注意:*a的两侧没有加括号,如果加了括号 int (*a)(int x,int y); 就是定义了一个指向函数的指针变量

43、a。,例7.13 有若干名学生的成绩(每个学生4门课程),要求在用户输入学生序号之后,输出该学生的全部成绩。 #include void main() float score4=60,70,80,90,56,89,67,88, 34,78,90,66; float *search(float (*pointer)4,int n); float *p; int i,m; printf(“Enter the number of student:“); scanf(“ ,score是一个二维数组,score指向数组的第一行,a. 形参pointer是一个指向一维浮点数组的指针 b. 函数的返回值,是

44、一个指向float型变量的指针。,实参score和形参pointer都是指向float型一维数组的指针,score传值给pointer。,float *search(float(*pointer)4,int n) float *pt; pt=*(pointer+n); return(pt); ,pt为指向浮点型变量的指针,pt=*(pointer+n); pointer接受来自实参score的值,指向二维数组的第0行,因此pointer+n指向二维数组的第n行。 *(pointer+n)即为第n行构成的一维数组的首地址。将*(pointer+n)赋值给pt,使得pt指向这个一维数组的首元素。然

45、后由return语句返回指针pt的值。,调用search函数返回的指针,即指向第n的学生的第一门成绩(这是第n行一维数组的第一个元素)。因此,可以使用循环语句打印*(p+i),即为各门成绩,指针数组和指向指针的指针,指针数组 本质是一个数组,其中每个元素均为指针类型,称为指针数组。 指针数组的一般定义形式: 类型名 *数组名数组长度; 例如: int *p4; 定义了一个一维数组p,该数组长度为4,每个数组元素都为指向整型变量的指针。,指针数组适合用来指向若干个字符串,使字符串处理更加灵活。 考虑:图书馆有若干本书,书名为字符串,因此考虑用字符数组来存放书名。因为每个书名都是一个字符串,那么很

46、多本书,就需要二维数组来存放。 从图中可以看出来,二维数组存放,比较浪费内存空间,且需要一个很大的连续内存空间才能存放。,F,o,l,l,o,w,m,e,0,B,A,S,I,C,G,r,e,a,t,W,a,l,l,0,F,O,R,T,R,A,N,0,C,o,m,p,u,t,e,r,d,e,s,i,g,n,0,0,指针数组的用途,如果使用指针数组,各元素分别指向各书名构成的字符串。这些字符串可单独存放,比用二维数组存放更节省空间。如果想对字符串排序也不用改变字符串的位置,直接对指针数组中的元素值进行修改,指向不同的字符串即可。,Follow me,BASIC,Great Wall,FORTRAN

47、,Computer design,name0,name1,name2,name3,name4,指针数组name,字符串,例7.14 将若干字符串按字母顺序输出 #include #include void main() void sort(char *name,int n); void print(char *name,int n); char *name=“Follow me“,“BASIC“, “Great Wall“, “FORTRAN“, “Computer design“; int n=5; sort(name,n); print(name,n); ,定义了一个指针数组name,它有5个元素,初值分别是“Follow me“, “BASIC“,“Great Wall“

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1