C语言教程课件Ch10指针_第1页
C语言教程课件Ch10指针_第2页
C语言教程课件Ch10指针_第3页
C语言教程课件Ch10指针_第4页
C语言教程课件Ch10指针_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第十章指 针本章主要内容指针和地址的概念指针变量指向数组/字符串时的操作指针变量做函数参数几种指针类型返回指针值的函数重点、难点如何理解指针和地址的概念灵活使用指向一位数组/字符串的指针灵活使用指针变量/数组名做函数参数掌握几种指针的概念与函数一章的例题结合,掌握参数单向传递的实质10.1 指针的概念10.2 变量的指针和指向变量的指针变量10.3 数组的指针和指向数组的指针变量10.4 字符串的指针和指向字符串的指针变量10.5 函数的指针和指向函数的指针变量10.6 返回指针的函数10.7 指针数组和指向指针的指针10.8 有关指针的数据类型和指针运算的小结1地址的概念 程序中每一个变量在

2、编译或运行时系统都为其分配内存单元,每一个内存单元(字节)都有一个相应的编号,这个编号称为该内存单元的“地址”,而内存单元中存入的内容则是该变量的值。内存用户数据区36920002000200220043010变量 i变量 j变量 k变量 i_pt10.1 指针的概念int i=3, j=6, k=9;int *i_pt;i_pt=&i;指针是c语言中比较灵活的数据结构,灵活地运用指针可以: (1) 有效地表示复杂的数据结构. (2) 动态分配内存. (3) 更方便地使用字符串和数组. (4) 直接处理内存地址.2对内存单元的存取有两种方式 (1)直接访问 按变量地址存取变量的值。 (2)间接

3、访问 将变量i的地址存放在另一个内存单元j中,要访问i, 则先按j的地址取出i的地址,再按i的地址取出i的值。直接访问和间接访问示意图3i20003ii_pt 20003指针变量的概念 一个变量的地址称为该变量的“指针”。 如果有一个变量专门用来存放另一个变量的地址(即指针),则它称为“指针变量”。指针变量的值是指针。一、指针变量的定义 指针变量必须在使用之前先定义,它是用来存放地址的。必须将它定义为“指针类型”。 定义的一般形式为: 类型标识符 *标识符注:(1) 标识符前面的“*”,表示该变量为指针变量。但指针变 量名是pt_1、pt_2、pt_3,而不是*pt_1、*pt_2、*pt_3

4、。(2) * 表示指向, 故*pt_1,*pt_2, *pt_3表示指针变量 pt_1, pt_2, pt_3所指向的变量。(3) 一个指针变量只能指向同一个类型的变量。10.2 变量的指针和指向变量的指针变量例: int *pt_1 ; char *pt_2 ; float *pt_3 ;二、指针变量的引用 有两个有关的运算符 (1) & 取地址运算符 (2) * 指针运算符(或称“间接访问”运算符)。例: int a, *pt; &a为变量a的地址, *pt为指针变量pt所指向的变量. 则: &*pt=&a=pt 则: *&a=*pt=a 则: (*pt)+相当于a+apt *pt若: p

5、t=&ab=(*pt)+;c=*pt+;b与c值是否相等? void main( ) int a,b,*p1,*p2; a=100; b=10; p1=&a; p2=&b; printf(%d,%dn,a,b); printf(%d,%dn,*p1,*p2); 例:1100,10100,10运行结果*p1ap1bp2&b*p210010&a例2: void main( ) int a,b,*p1,*p2,*p; scanf(%d %d,&a,&b); p1=&a; p2=&b; if(ab) p=p1;p1=p2;p2=p; printf(%d,%dn,a,b); printf(%d,%dn,

6、*p1,*p2); 输入:5 9*p1ap1bp2&b*p2 5 9&ap&b&a输出: 5,99,5void main( )int a,b,*p1,*p2,t; scanf(%d %d,&a,&b); p1=&a; p2=&b; if(ab) t=*p1;*p1=*p2;*p2=t; printf(%d,%dn,a,b); &a*p1*p2三、指针变量作为函数参数。 例1:输入a和b两个整数,按先大后小的顺序输出a和b。 void main ( ) int a,b; int *point_1,*point_2; scanf(%d%d,&a,&b); point_1=&a;point_2=&b

7、; if(ab) swap(point_1,point_2); printf(n%d,%dn,a,b); printf(n%d,%dn,*point_1,*point_2); 输入数据: 4 8输出结果: 8 , 4 8 , 4void swap(int *p1,int *p2)int p; p=*p1;*p1=*p2; *p2=p;abpoint_1point_2&a&b48p1p284point_1point_2&a&bvoid swap(int *p1,int *p2)int *p; p=p1;p1=p2; p2=p;void main ( ) int a,b; int *point_1

8、,*point_2; scanf(%d%d,&a,&b); point_1=&a;point_2=&b; if(ab) swap(point_1,point_2); printf(n%d,%dn,a,b); printf(n%d,%dn,*point_1,*point_2); a b point_1point_2输入数据: 4 84 8p1p2 point_1point_2输出结果:4,84,8注:1.不能企图通过改变形参地址而使实参地址也改变, 也就是说调用函数不能改变实参指针变量的值。 2.调用函数可以改变实参指针变量所指变量的值。ap1bp2cp3例2:输入a,b,c 三个整数,按大小顺

9、序输出。void swap(int *pt1,int *pt2)int *pt1,*pt2;int p; p=*pt1; *pt1=*pt2; *pt2=p; void exchange(q1,q2,q3)int *q1,*q2,*q3; if(*q1*q2) swap(q1,q2); if(*q1*q3) swap(q1,q3); if(*q2*q3) swap(q2,q3); void main() int a,b,c,*p1,*p2,*p3; scanf(%d%d%d,&a,&b,&c); p1=&a;p2=&b;p3=&c; exchange(p1,p2,p3); printf(n%d

10、,%d,%dn,a,b,c); 5103&b&a&cq1q2q3pt1pt210 5q1q2q3 10.3 数组的指针和指向数组的指针变量一、指向数组元素的指针变量 与前面介绍的指向变量的指针变量相同。若: int a10,*p; p=&a0;则: (1) p+i和a+i就是ai的地址,或者说它们指向数组的第i个 元素。 (2) *(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即ai。 (3) 指向数组的指针变量可以带下标,如pi与*(p+i)等价。 数组的指针是指数组的起始地址,数组元素的指针是数组元素 的地址。指针法:main( )int *p,i,a10; p=&a0; fo

11、r(i=0;i10;i+) scanf(%d, p+); printf(n); p=&a0; for (i=0;i10;i+) printf(%3d,*p+); pa0a1a2a9例1:输出数组全部元素。(设a数组,整型,10个元素)3p5pp-4p12pp*(p+i);p+i); p=a; p=a;(2)下标法main ( )int a10; int i; for (i=0;i10;i+) scanf(%d,&ai); printf(n); for (i=0;i10;i+) printf(%3d,ai); (3)地址法main ( )int a10; int i; for (i=0;i10;

12、i+) scanf(%d,a+i); printf(n); for (i=0;i10;i+) printf(%3d,*(a+i); 在使用指针变量时应注意的几个问题: 1. 数组名是数组的首地址,因此 p=&a0 与 p=a 等价。 2指针变量可以实现使本身的值改变,数组名不可以。 例: p+正确 a+不正确 3要注意指针变量的当前值。 4指针变量可以指到数组后的内存单元。 5注意指针变量的运算,若先使p指向数组a(即p=a),则 (1) p+ (或p+=1) 指向下一个元素。 (2) *p+等价于*(p+)先得到p指向的变量的值,p再 加1。 (3) *(p+)与*(+p)作用不同,前者先取

13、*p,后使p加 1;后者相反。 (4) (*p)+表示p所指向的元素值加1。 (5) 若p当前指向a数组第i个元素,则: *(p-)相当于ai-,先取p值作*运算,再使p自减; *(+p)相当于a+i,先使p自加,再作*运算; *(-p)相当于a-i,先使p自减,再作*运算。二、数组名作函数参数 用数组名作参数,在调用函数时实际上是把数组的首地址传给形参,这样实参与形参共同指向同一段内存。因而调用过程中,如形参数组元素值发生变化也就使实参数组的元素发生了变化,但这种变化并不是从形参传回实参的,而是由于形参与实参共享同一段内存而造成的。 例2:将数组a中n个整数按相反顺序存放。245760119

14、7337911067542imjvoid inv(int x,int n)int i,j,t,m=n/2; for (i=0;im;i+) j=n-1- i; t=xi; xi=xj; xj=t; void main ( )int i ,a10=3,7,9,11,0,6,7,5,4,2; printf(The original array:n); for (i=0;i10;i+); printf(%3d,ai); printf(n); inv(a,10); printf(The array has been inverted:n); for (i=0;i10;i+) printf(%3d,ai

15、); printf(n); void inv(int *x, int n) int t,*i,*j; j=x+n-1; for (i=x;ij;i+,j-) t=*i; *i=*j; *j=t; a0a1a2a3a937911067542a4a5a6a7a8a 数组i, xp=x+mj若将形参改为指针,则inv函数可改为:27911067543ji24911067573ij 如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下几类情况: (1) 形参和实参都用数组名 传递的是实参数组首地址,形参与实参共用同一段内存单元。 (2) 实参用数组名,形参用指针变量 通过指针

16、变量值的改变可以指向实参数组的任一元素。 (3) 实参和形参都用指针变量 先使实参指针变量指向数组的首地址,然后将实参的值 传给形参,通过指针变量值的改变可以使其指向数组的每个元素。 (4) 实参为指针变量,形参为数组名 设p为指针变量,令p=&a0,p为实参,对应的形参x为数组名,则函数调用时将 p的值传给形参数组名x,也就是使其取得 a数组的首地址,使 x数组和 a数组共用同一段内存单元.例3:用选择法对10个整数排序。void sort(int x ,int n)int i,j,k,t; for (i=0;in-1;i+) k=i; for (j=i+1;jxk) k=j; if (k!

17、=i) t=xi;xi=xk;xk=t; void main ( ) int *p,i,a10; p=a; for (i=0;i10;i+) scanf(%d,p+); p=a; sort(p,10); for (p=a,i=0;i10;i+) printf(%d,*p+); (1) 实参用指针变量,形参用数组名(2) 实参用数组名,形参用指针变量void sort(int *x,int n)int i,j,k,t; for (i=0;in-1;i+) k=i; for (j=i+1;j*(x+k) k=j; if (k!=i) t=*(x+i); *(x+i)=*(x+k); *(x+k)=

18、t; void main ( ) int i,a10; for (i=0;i10;i+) scanf(%d,&ai); sort(a,10); for (i=0;i10;i+) printf(%3d,ai); (3) 实参用指针变量,形参也用指针变量void main ( ) int *p,i,a10; p=a; for (i=0;i10;i+) scanf(%d,p+); p=a; sort(p,10); for (p=a,i=0;i10;i+) printf(%d,*p+); void sort(int *x,int n)int i,j,k,t; for (i=0;in-1;i+) k=i

19、; for (j=i+1;j*(x+k) k=j; if (k!=i) t=*(x+i); *(x+i)=*(x+k); *(x+k)=t; 例4:从10个数中找出其中最大值和最小值。int max,min;void main ( )int i,number10; void max_min_value( ); printf(enter 10 datan); for (i=0;i10;i+) scanf(%d,&numberi); max_min_value(number,10); printf(n max=%d,min=%d,max,min); 方法1:外部变量void max_min_val

20、ue(int array , int n) int *p,*array_end; array_end=array+n; max=min=*array; for (p=array+1;pmax) max=*p; else if (*pmin) min=*p; number 2 32 -12 4 56 7 28 -67 39 41arrayarray_endp22maxmin32p-12pp 56ppp-67ppp*array void main( ) int i,number10; int amax,amin,*amax_p,*amin_p; void max_min_value( ) ; pr

21、intf(enter 10 datan); for (i=0;i10;i+) scanf(%d,&numberi); amax=amin=number0; amax_p=&amax;amin_p=&amin; max_min_value(number,10,amax_p,amin_p); printf(max=%d,min=%dn,*amax_p,*amin_p); 方法2:amaxaminamax_pamin_p12 -23 5 78 27 6 9 36 3 41212 void max_min_value(int array,int n,int *a1,int *b1) int i; fo

22、r (i=1;i*a1) *a1=arrayi; else if (arrayi*b1) *b1=arrayi; amaxaminamax_pamin_p12 -23 5 78 27 6 9 36 3 41212max_min_value(number,10,amax_p,amin_p);array10na1b1三、指向多维数组的指针和指针变量int a34= 6,9,0,16,8,-1,2,7,3,48,-5,12;(1) a+i=ai=*(a+i) a=a0=*(a+0)=*a=&a00aa+0a+1a+2a0a1a2 (2) ai+j是aij的地址 *(a+i)+j也是aij的地址(3)

23、 &ai或a+i指向行,*(a+i)或ai指向列(4) aij的值可以表示为: *(ai+j) *(*(a+i)+j) aij690168-127348-5121多维数组的地址对于一维数组ai=*(a+i)=*(p+i)=pi#define FORMAT %d,%dnvoid main ( )static int a34=1,3,5,7,9,11,13,15,17,19,21,23; printf (FORMAT,a,*a); printf (FORMAT,a0,*(a+0); printf (FORMAT,&a0,&a00); printf (FORMAT,a1,a+1); printf (

24、FORMAT,&a10,*(a+1)+0); printf (FORMAT,a2,*(a+2); printf (FORMAT,&a2,a+2); printf (FORMAT,a10,*(*(a+1)+0);运行结果:158,158158,158158,158166,166166,166174,174174,1749, 9 2多维数组的指针可以用指针变量指向多维数组及其元素 (1) 指向数组元素的指针变量。例5:用指针变量输出数组元素的值。 void main( ) static int a23=2,3,6,7,8,5; int i,j,*p; p=&a00; /* p=a0; 或 p=*a

25、;*/ for(i=0;i2;i+) for(j=0;j3;j+,p+) printf(%3d,*p); printf(n); 2 3 6 7 8 5aa0a1p23 2 3 6pp6p7p8p5p例6:用指针变量输出数组元素aij的值。 void main( ) static int a23=2,3,6,7,8,5; int i,j,*p; p=a; scanf(%d %d,&i,&j); printf(%3d,*(p+i*3)+j); void main() static int a45=1,4,2,3,7,6,9,10,8,-1, -2,-6,-4,4,2,7,6,9,11,14; in

26、t i,j; for(i=0;i4;i+) for(j=0;j5;j+) printf(%4d,aij); printf(n); sort(a,4*5); printf(=n); for(i=0;i4;i+) for(j=0;j5;j+) printf(%4d,aij); printf(n); 例7: 将一个二维数组a45进行按行全排序 void sort(int *p,int n) int i,j,t; for(i=0;in-1;i+) for(j=i+1;j=n-1;j+) if(*(p+i)*(p+j) t=*(p+i); *(p+i)=*(p+j); *(p+j)=t; a00a01a

27、02a03a04a10a11a12a13a14 . . .a32a33a34.sort(a,4*5);p(2) 指向由m个整数组成的一维数组的指针变量。例7:输出二维数组任一行任一列的元素的值。 void main ( )static int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4,i,j; p=a; scanf(i=%d,j=%d,&i,&j); printf(a%d,%d=%dn,i,j,*(*(p+i)+j); 说明: (1) int (*p)4 表示p指向一个包含4个元素的一维数组. (2) p+1使指针移动2*4个字节, *(p+1

28、)使指针的指向由横 向转向纵向. (3) *(p+i)+j使指针移动2*4*i+2*j.(3) 多维数组的指针作函数参数。 例9: 求二维数组a45每列最大值 void colum_max(a,b) int (*a)5,*b; int i,j; for(j=0;j5;j+) for(i=1;i4;i+) if (*(b+j)*(*(a+i)+j) *(b+j)=*(*(a+i)+j); int a45,b5;colum_max(a,b);a+0a+1a+2a+3b 2 12 3 27 -4 3 7 33 2 5 1 6 12 3 15 4 8 10 9 14 2 12 3 27 -4.34123327515 void main( ) int a45,b5; int i,j; for(i=0

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论