c语言程序设计》10-指针.ppt

上传人(卖家):晟晟文业 文档编号:3714042 上传时间:2022-10-06 格式:PPT 页数:69 大小:216.82KB
下载 相关 举报
c语言程序设计》10-指针.ppt_第1页
第1页 / 共69页
c语言程序设计》10-指针.ppt_第2页
第2页 / 共69页
c语言程序设计》10-指针.ppt_第3页
第3页 / 共69页
c语言程序设计》10-指针.ppt_第4页
第4页 / 共69页
c语言程序设计》10-指针.ppt_第5页
第5页 / 共69页
点击查看更多>>
资源描述

1、c语言程序设计10-指针 10 101 1 指针的概念指针的概念 简单地说,简单地说,指针就是地址指针就是地址。要掌握指针的概念就必须弄清:要掌握指针的概念就必须弄清:内存地址概念内存地址概念?变量与地址的关系变量与地址的关系?如何通过地址进行变量的存取如何通过地址进行变量的存取?说明例:说明例:内存用户数据 1000 3 i 1002 6 j 1004 9 k对变量值的存取总是按地址进行的-直接访问。int i,j,k;i=3;j=6;k=i+j;程序经编译后程序经编译后,变量名就不,变量名就不复存在,以地复存在,以地址对应。址对应。也可以采用也可以采用“间接访问间接访问”方式:方式:先将变

2、量先将变量i i的地址存放到另一变量的地址存放到另一变量p1p1中,中,要访问要访问i i时,先取出时,先取出p1p1的内容(变量的内容(变量i i的地址),的地址),再去访问该地址所对应的内存单元中的内容再去访问该地址所对应的内存单元中的内容(变量(变量i i的值)。的值)。内存用户数据 1000 3 i 1002 6 j 1004 9 k 2000 1000 p1 2004 1002 p2int i,j,k;i=3;j=6;k=i+j;int *p1,*p2;p1=&i;p2=&j;在以上概念的基础上对指针下定义:在以上概念的基础上对指针下定义:变量的地址就是该变量的变量的地址就是该变量的

3、指针指针。存放地址的变量称存放地址的变量称指针变量指针变量。若若p1p1存放了变量存放了变量i i的地址,的地址,则称则称p1p1是是指向变量指向变量i i的指针变量的指针变量。10001002100410001002ijkp1p2369int i,j,k;i=3;j=6;k=i+j;int *p1,*p2;p1=&i;p2=&j;10 102 2 变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量 变量的指针变量的指针 指针变量指针变量 指向变量的指针变量指向变量的指针变量 用用“*”代表代表“指向指向”如如*p1p1代表它所指向的变量代表它所指向的变量i i,同一内存单元。,同一

4、内存单元。以下两个语句等价:以下两个语句等价:i=3;i=3;直接访问直接访问 *p1=3;p1=3;间接访问间接访问int i,int i,*p1;p1;p1=&i;p1=&i;内存用户数据 1000 3 i 1002 6 j 1004 9 k 2002 1000 p1 2004 1002 p2int i,j,k;i=3;j=6;k=i+j;int*p1,*p2;p1=&i;p2=&j;*p1=5;*p2=8;58 指针变量的定义指针变量的定义 指针变量也必须先定义后使用。指针变量也必须先定义后使用。int int *p1;p1;注意:注意:*表示该变量为指针变量,但变量名是表示该变量为指针

5、变量,但变量名是p1p1。一个指针变量只能指向同一类型的变量。一个指针变量只能指向同一类型的变量。int i,int i,*p1;p1;float a;float a;p1=&i;p1=&i;合法合法 p1=&a;p1=&a;不合法不合法 指针变量的引用指针变量的引用 两种用法:两种用法:用地址运算符用地址运算符&p1=&i p1=&i;用指针运算符用指针运算符*(实行间接访问)(实行间接访问)*p1=100;k=p1=100;k=*p1;p1;注意:注意:指针变量只能放地址(指针)。指针变量只能放地址(指针)。p1=100;p1=100;不允许不允许 使用指针运算符使用指针运算符*之前,之前

6、,p1p1必须被赋值(即必须被赋值(即p1p1必必须存放了某个变量的地址)须存放了某个变量的地址)例:例:T10-1.c 注意:要区别定义和引用中的“*”main()int a=100,b=10;int *p1,*p2;定义指针变量,尚无体定义指针变量,尚无体指向指向 p1=&a;p1p1指向指向a a p2=&b;p2p2指向指向b b printf(“*p1=%d,*p2=%d n”,*p1,*p2);printf(“&a=%x,&b=%x n”,&a,&b);printf(“p1=%x,p2=%x n”,p1,p2);printf(“&p1=%x,&p2=%x n”,&p1,&p2);运

7、算结果:*p1=100,*p2=10&a=12ff7c,&b=12ff78p1=12ff7c,p2=12ff78&p1=12ff74,&p2=12ff70要特别注意以下用法的后果:要特别注意以下用法的后果:egp1.c int *p1;*p1=100;例:输入例:输入a a和和b b两个整数,按先大后小的顺序输出两个整数,按先大后小的顺序输出 main()T10-2.c int a,b,*p1,*p2,*p;scanf(“%d,%d”,&a,&b);1000 5 a p1=&a;p2=&b;1002 9 b if(ab)p=p1;p1=p2;p2=p;printf(“n%d,%d”,a,b);

8、2000 p1 printf(“n%d,%d”,*p1,*p2);2004 p2 2006 p 改变p1和p2的指向10001002100210001000重要概念:重要概念:只要将某一变量的地址存入指针变量中,只要将某一变量的地址存入指针变量中,就可通过指针变量间接访问该变量。就可通过指针变量间接访问该变量。配钥匙!配钥匙!swap(int p1,int p2)int t;t=p1;p1=p2;p2=t;1000 5 a 1002 9 b main()int a,b;scanf(“%d,%d”,&a,&b);2000 p1 if(ab)swap(a,b);2004 p2 printf(“n%

9、d,%d”,a,b);2006 t T10-3-1.c59 595例 不用指针变量作函数参数,将两个整数按大小顺序输出。怎样直接修改a、b的值呢?修改原件修改原件用指针!用指针!指针变量作为函数的参数指针变量作为函数的参数 可将指针变量作函数的参数,接受实参可将指针变量作函数的参数,接受实参地址,获得具体指向,进而通过指针变量间地址,获得具体指向,进而通过指针变量间接访问主调函数的变量。接访问主调函数的变量。例T10-3.c用指针变量作函数参数,将两个整数按大小顺序输出。swap(int *p1,int *p2)int t;t=*p1;*p1=*p2;*p2=t;1000 5 a 1002 9

10、 b main()int a,b;scanf(“%d,%d”,&a,&b);2000 p1 if(ab)swap(&a,&b);2004 p2 printf(“n%d,%d”,a,b);2006 t 10001002595 重要概念:重要概念:使用指针变量作函数参数,使用指针变量作函数参数,被调函数可以将多个结果交给主调函数。被调函数可以将多个结果交给主调函数。数组名做参数,可返回该数组所有元素数组名做参数,可返回该数组所有元素 还记得那个求成绩最高、最低和平均值还记得那个求成绩最高、最低和平均值的例子?还需要用全局变量吗?的例子?还需要用全局变量吗?例例T10-4-2.c T10-4-2.c

11、:求:求n n个数的最大值、最小值和平均值。个数的最大值、最小值和平均值。float aver(int a,int n,int*max,int*min)int i;float s=0;*max=a0;*min=a0;for(i=0;i*max)*max=ai;if(ai*min)*min=ai;return(s/100);main()int a100,i,max,min;float av;for(i=0;i100;i+)scanf(“%d”,&ai);av=aver(a,100,&max,&min);printf(“%d,%d,%f”,max,min,av);例例T10-4-1.c:编写函数,

12、求一元二次方程的两个实根。:编写函数,求一元二次方程的两个实根。#include “math.h”?root(float a,float b,float c,)float d;d=b*b-4*a*c;if(d0|a=0)return(0);?=(-b+sqrt(d)/2/a;?=(-b-sqrt(d)/2/a;return(1);float *x1,float*x2*x1*x2 int main()int k;float a,b,c,x1,x2;scanf(“%f,%f,%f”,&a,&b,&c);k=root(a,b,c,&x1,&x2);if(k)printf(“n%f,%f”,x1,x2

13、);输入:1,-10,25输出:5.000000,5.000000函数参数:函数参数:如不需改变(只读):一般参数如不需改变(只读):一般参数如需改变(读写):指数参数如需改变(读写):指数参数 10 103 3 数组的指针和指向数组的指针变量数组的指针和指向数组的指针变量数组有一个首地址:数组的指针数组的指针。每个数组元素也都有地址:数组元素的指针数组元素的指针。532168742000200220042006 指向数组元素的指针变量指向数组元素的指针变量 int a10,*p;p=a;指向数组指向数组 p=&a0;指向数组元素指向数组元素 5124768039200020022004200

14、6p 通过通过指针引用数组元素指针引用数组元素 int a10,*p;p=&a0;或者或者 p=a;/p p指向指向a0a0 *p=1;等效于等效于a0=1a0=1;即可通过即可通过p p来访问来访问a0a0也可以通过也可以通过p p来访问其它元素:来访问其它元素:*(p+1)=3;(p+1)=3;等效于等效于a1=3;a1=3;其中其中p+1p+1指向指向a1a1注意:注意:p+1p+1不是地址加不是地址加1 1,而是加一个数据类型单,而是加一个数据类型单位。位。一般地一般地,当当p p指向指向a0a0时时,即即p=&a0;或者或者 p=a;p+i a+i a+i&ai&ai*(p+i)*(

15、a+i)(a+i)ai ai pi pi即以下几个语句等效:即以下几个语句等效:ai=10;*(p+i)=10;*(a+i)=10;pi=10;举例:用三种方法输出数组元素例T10-5-1.c 用“数组名数组名+下标下标”的方法main()int i,a5;for(i=0;i5;i+)scanf(“%d”,&ai);for(i=0;i5;i+)printf(“&a%d=%x,a%d=%d n”,i,&ai,i,ai);输入:55 66 77 88 99 输出:&a0=ffce,a0=55&a1=ffd0,a1=66&a2=ffd2,a2=77&a3=ffd4,a3=88&a4=ffd6,a4=

16、99 ffcc 55 a0ffce 66 a1ffd0 77 a2ffd2 88 a3ffd4 99 a4ffd6 a5举例:用三种方法输出数组元素例T10-5-2.c 计算“数组名计算地址数组名计算地址”的方法main()int i,a5;for(i=0;i5;i+)scanf(“%d”,a+i);for(i=0;i5;i+)printf(“a+%d)=%x,*(a+%d)=%d n”,i,(a+i),i,*(a+i);输出:(a+0)=ffcc,*(a+0)=55 (a+1)=ffce,*(a+1)=66 (a+2)=ffd0,*(a+2)=77 (a+3)=ffd2,*(a+3)=88

17、(a+4)=ffd4,*(a+4)=99 ffcc 55 a0ffce 66 a1ffd0 77 a2ffd2 88 a3ffd4 99 a4ffd6 a5举例:用三种方法输出数组元素例T10-5-3_new.c 用“指针变量指针变量+下标下标”的方法(指针法指针法I)main()int *p,a5,i;p=a;for(i=0;i5;i+)scanf(“%d”,p+i);for(i=0;i5;i+)printf(&p%d=%x,p%d=%d,*(p+%d)=%dn,i,&pi,i,pi,i,*(p+i);12ff6c 55 p012ff70 66 p112ff74 77 p212ff78 88

18、 p312ff7c 99 p4输出:&p0=12ff6c,p0=55,*(p+0)=55&p1=12ff70,p1=66,*(p+1)=66&p2=12ff74,p2=77,*(p+2)=77&p3=12ff78,p3=88,*(p+3)=88&p4=12ff7c,p4=99,*(p+4)=99举例:用三种方法输出数组元素(例T10-5-4_new.c)用“指针变量指向数组元素指针变量指向数组元素”法(指针法指针法II)main()int *p,a5;for(p=a;p(a+5);p+)scanf(“%d”,p+i);for(p=a;p(a+5);p+)printf(“p=%x,*p=%d n

19、”,p,*p);输出:p=12ff6c,*p=55p=12ff70,*p=66p=12ff74,*p=77p=12ff78,*p=88p=12ff7c,*p=9912ff6c 55 a012ff70 66 a112ff74 77 a212ff78 88 a312ff7c 99 a4p+:合法,因p是指针变量,而变量可以用+运算符的a+:不合法,因为a是数组名,其值是数组元素的首地址,分配之后不可变。举例:用三种方法输出数组元素(例T10-5-4.c)指针变量当作数组名使用(混合指针法)main()int a5,*p=a,i;for(p=a;pa+5;p+)scanf(“%d”,p);p=a;/

20、不能漏!不能漏!for(i=0;i5;i+)printf(“&p%d=%x,p%d=%d,*(p+%d)=%dn”,i,&pi,i,pi,i,*(p+i);输出:&p0=12ff6c,p0=55,*(p+0)=55&p1=12ff70,p1=66,*(p+1)=66&p2=12ff74,p2=77,*(p+2)=77&p3=12ff78,p3=88,*(p+3)=88&p4=12ff7c,p4=99,*(p+4)=9912ff6c 55 p12ff70 66 p+112ff74 77 p+212ff78 88 p+312ff7c 99 p+4通过通过指针引用数组元素的方法小结指针引用数组元素的

21、方法小结例:累加求和的各种用法:例:累加求和的各种用法:int*p,a10;s=0;p=a;for(i=0;i10;i+)s+=ai;for(i=0;i10;i+)s+=*(a+i);for(i=0;i10;i+)s+=*(p+i);for(i=0;i10;i+)s+=pi;for(i=0;i10;i+)s+=*p+;for(p=a;pa+10;p+)s+=*p;最后一种用法效率高。数组元素地址法数组元素地址法指针法指针法I指针变量指向数组元素指针法II指针变量当作数组名注意不能注意不能使用a+指针变量使用时的几个问题,指针变量使用时的几个问题,若若p当前指向当前指向a数组的第数组的第i个元素

22、,则:个元素,则:10-plus.c *p:是取出是取出ai的值的值.p+:指针指向指针指向ai+1.*p+:等价于等价于*(p+)及及ai+,优先级同为优先级同为2,从右向左结合从右向左结合,将将 ai 的值取出的值取出,后再使后再使 p增增1(不是单纯的加一,是不是单纯的加一,是p指向指向ai+1).*(+p):与与a+i等价,先将等价,先将p指向指向ai+1,然后将该元素取出然后将该元素取出.(*p)+:将将p所指的数组元素所指的数组元素ai的值取出的值取出,使使ai的值增的值增1.p-:指针指向指针指向ai-1.*(p-):与与ai-等价,等价,将将p 所指向的第所指向的第i个数组元素

23、取出个数组元素取出,然后使然后使p指向指向i-1元素元素.*(-p):与与a-i等价,先将等价,先将p减减1指向第指向第i-1个元素个元素,然后将其取出然后将其取出.(*p)-:将将p所指的数组元素所指的数组元素ai的值取出的值取出,使使ai的值减的值减1.数组名作为函数参数数组名作为函数参数 有了指针概念的基础上,重新回顾数组名作有了指针概念的基础上,重新回顾数组名作为函数参数时,数据的传递情况:为函数参数时,数据的传递情况:void sort(void sort(int aint a,int n),int n)void sort(void sort(int int*a a,int n),i

24、nt n)例:例:选择法排序函数选择法排序函数 void sort(int *a,int n)例T10-7-1.c int i,j,t;for(i=0;in-1;i+)for(j=i+1;jaj)t=ai;ai=aj;aj=t;只将形参改为指针变量,仍按下标法使用只将形参改为指针变量,仍按下标法使用 void sort(int *a,int n)int i,j,t;for(i=0;in-1;i+)for(j=i+1;j*(a+j)t=*(a+i);*(a+i)=*(a+j);*(a+j)=t;按指针法使用按指针法使用例T10-7-2.c 进一步优化:都用指针,效率更高!进一步优化:都用指针,效

25、率更高!(例T10-7-3.c)void sort(int *a,int n)int *i,*j,t;for(i=a;ia+n-1;i+)for(j=i+1;j*j)t=*i;*i=*j;*j=t;main()int a10,j;for(j=0;j10;j+)scanf(“%d”,a+j);sort(a,10);for(j=0;j10;j+)printf(“%5d”,aj);分段排序?分段排序?例T10-7-4.c main()int a10,j;for(j=0;j10;j+)scanf(“%d”,a+j);for(j=0;j10;j+)printf(“%5d”,aj);sort(a,5);s

26、ort(a+5,5);void sort(int *a,int n)int *i,*j,t;for(i=a;ia+n-1;i+)for(j=i+1;j*j)t=*i;*i=*j;*j=t;指向多维数组的指针和指针变量指向多维数组的指针和指针变量 从本质上说,多维数组的指针与一维数组从本质上说,多维数组的指针与一维数组的指针相同,但在概念上和使用上,多维数组的指针相同,但在概念上和使用上,多维数组的指针要复杂些。的指针要复杂些。以二维数组的指针为例:以二维数组的指针为例:二维数组的地址:一维:a,&ai,a+i 二维:aa+i(行指针:指向第i行)ai*(a+i)(特殊的一维数组,列指针,指向行

27、中的列)ai+j *(a+i)+j&aij int a34 1357911131517192123100010081016a+0a+1a+2a0讨论以下用法的效果:讨论以下用法的效果:T10-8-1.cfor(i=0;i3;i+)scanf(“%d”,a+i);输入数据:输入数据:1 2 3讨论以下用法的效果:讨论以下用法的效果:T10-8-2.cfor(i=0;i3;i+)scanf(“%d”,a1+i);输入数据:输入数据:1 2 3讨论以下用法的效果:讨论以下用法的效果:T10-8-3.cfor(i=0;i3;i+)scanf(“%d”,a1+i+2);输入数据:输入数据:1 2 3讨论

28、以下用法的效果:讨论以下用法的效果:T10-8-4.cfor(i=0;i3;i+)scanf(“%d”,a+i+1);输入数据:输入数据:1 2 3a0+1 a0+2 a0+3一维数组与二维数组的比较一维数组与二维数组的比较第第i个个一维数组一维数组的第的第j个元个元素的地址素的地址无意义无意义*(a+i)+j第第i个个一维数组一维数组的第的第j个元个元素的值素的值无意义无意义*(*(a+i)+j)第第i个个一维数组一维数组的值的值第第i个个一维数组一维数组的首地址的首地址第第i个元素的值个元素的值*(a+i)第第i个个元素元素 的地址的地址一维数组一维数组第第i个元素的地址个元素的地址a+i

29、二维数组的首地址二维数组的首地址一维数组的首地址一维数组的首地址a二维数组二维数组一维数组一维数组注意:注意:指针运算符指针运算符*作用在行指针上的结果仍是指针作用在行指针上的结果仍是指针-列指针列指针;*作用在列指针上的结果作用在列指针上的结果-具体元素具体元素。*(a+0),*(a+1),*(a+2)仍是地址仍是地址。*(a+i)ai *(a0),*(a1),*(a1)具体元素值具体元素值。*(ai)*(a+i)+j 也是地址,但要区别:也是地址,但要区别:(a+i)+j行指针行指针 (a+1)+1?*(a+i)+j列指针列指针 *(a+1)+1?100010081016a+0a+1a+2

30、a0a1a2*(a+1)1357911131517192123 如果要通过如果要通过a+ia+i形式的地址访问数组元素的具体形式的地址访问数组元素的具体内容,则:内容,则:*(*(a+i)或或 *(*(a+i)+j)如如:*(*(a+1)a10 *(*(a+1)+2)a12讨论:讨论:例T10-8-5.c*(a+2)*(*(a+1)+3)*(a1+1)*(*(a+1)+5)123456789111012例:求数组例:求数组a a的所有元素之和。的所有元素之和。可有多种用法:可有多种用法:例T10-9-1.cT10-9-3.c M M行行N N列列for(i=0;iM;i+)for(i=0;iM

31、;i+)for(i=0;iM;i+)for(i=0;iM;i+)for(j=0;jN;j+)for(j=0;jN;j+)for(j=0;jN;j+)for(j=0;jN;j+)s+=s+=aijaij;s+=;s+=*(ai+j)(ai+j);for(i=0;iM;i+)for(i=0;iM;i+)for(j=0;jN;j+)for(j=0;jN;j+)s+=s+=*(*(a+i)+j)(a+i)+j);aij*(ai+j)*(*(a+i)+j)指向二维数组的指针变量指向二维数组的指针变量 同样可使一个指针变量同样可使一个指针变量p p指向二维数组指向二维数组a a,再,再通过通过p p访问数

32、组元素。访问数组元素。例T10-10.cmain()main()int a34=1,2,3,4,5,6,7,8,9,10,11,12;int a34=1,2,3,4,5,6,7,8,9,10,11,12;int i,k,int i,k,*p;p;p=a;p=a;k=k=*p;p;?k=k=*(p+2);(p+2);?for(p=a;pa+2;p+)printf(for(p=a;pa+2;p+)printf(“%3d,%3d,”,*p);p);?N列:列:aij*(p+i*N+j)pi*N+j123456789101112k=p12;不合法不合法k=*(*(p+1)+2);k=p1*4+2;合法

33、合法k=*(p+1*4+2);例:求矩阵的上三角元素之和。例:求矩阵的上三角元素之和。例T10-11.cmain()int a34,*p,i,j,s=0;输入输入a p=a;for(i=0;i3;i+)for(j=i;j4;j+)s+=pi*4+j;或或 s+=*(p+4*i+j)printf(“n%d”,s);/s=54N列:列:aij*(p+i*N+j)pi*N+j123456789101112 多维数组的指针作函数参数维数组的指针作函数参数 用于接受实参数组地址的形参可用两种:用于接受实参数组地址的形参可用两种:行指针行指针和和列指列指针针。以方阵转置为例:以方阵转置为例:例T10-13

34、-1.c void at(int void at(int (*p)3p)3)用行指针用行指针 int i,j,t;int i,j,t;缺点:不通用(必须制定列数)缺点:不通用(必须制定列数)for(i=0;i3;i+)for(i=0;i3;i+)for(j=i+1;j3;j+)for(j=i+1;j3;j+)t=pij;pij=pji;t=pij;pij=pji;pji=t;pji=t;p p指向一个包含指向一个包含3 3个整形元素的一维数组(行指针),个整形元素的一维数组(行指针),p p相相当于一个二维数组!当于一个二维数组!用列指针:用列指针:例T10-13-2.c void at(in

35、t void at(int *p p,int ,int n n)/n)/n为列数为列数 int i,j,t;int i,j,t;for(i=0;i for(i=0;in n;i+);i+)for(j=i+1;j for(j=i+1;jn n;j+);j+)t=t=pipi*n+jn+j;pipi*n+jn+j=pjpj*n+in+i;pjpj*n+in+i=t;=t;优点:通用 在编通用函数时,一般使用列指针。用列指针:用列指针:例T10-13-3.c int sum(int int sum(int*p p,int,int m m,int,int n n)/m)/m行行n n列列 int i,

36、j,s=0;int i,j,s=0;for(i=0;im;i+)for(j=i;jn;j+)s+=pi*n+j;或或 s+=*(p+n*i+j)return(s);优点:通用 在编通用函数时,一般使用列指针。10104 4 字符串的指针和指向字符串的指针变量字符串的指针和指向字符串的指针变量 字符串的表示形式字符串的表示形式 可用两种方法访问字符串:可用两种方法访问字符串:用字符数组存放字符串用字符数组存放字符串 用字符指针指向一个字符串用字符指针指向一个字符串例T10-14.cmain()main()char str5=”abc”;char str5=”abc”;定义字符数组,并将字符串定义

37、字符数组,并将字符串存入存入 char char *p=str;p=str;定义指针变量,指向字符串定义指针变量,指向字符串 printf(“%s”,str);printf(“%s”,str);通过数组名访问字符串通过数组名访问字符串 printf(“%s”,p);printf(“%s”,p);通过指针变量访问字符串通过指针变量访问字符串 printf(“%c”,printf(“%c”,*(p+2);(p+2);通过指针变量访问字符通过指针变量访问字符 strab c0abc010001000p 与其它一维数组的指针相比,字符串的指与其它一维数组的指针相比,字符串的指针有其针有其独特之处独特之

38、处:可以通过指针对字符串进行整体访问。可以通过指针对字符串进行整体访问。对字符串的操作依赖于对字符串的操作依赖于结束符结束符。可以可以整体赋初值整体赋初值。有各种字符串处理函数。有各种字符串处理函数。本节重点掌握:本节重点掌握:通过数组和通过指针操作字符串的通过数组和通过指针操作字符串的基本方法。基本方法。常用的字符串处理方法。常用的字符串处理方法。例:字符串拷贝操作。例:字符串拷贝操作。例T10-15-1.c,例T10-15-2.cmain()char a=”abcdef”,b20;int i;for(i=0;*(a+i)!=0;i+)*(b+i)=*(a+i);*(b+i)=0;print

39、f(“%s”,b);main()char a=”abcdef”,b20,*p1,*p2;p1=a;p2=b;for(;*p1!=0;p1+,p2+)*p2=*p1;*p2=0;printf(“%s”,b);用指针变量处理将拷贝操作编成一函数:将拷贝操作编成一函数:例T10-15-3.c,例T10-15-4.cvoid copy_string(char *from,char *to)for(;*from;from+,to+)*to=*from;*to=0;还可以改成:还可以改成:void copy_string(char *from,char *to)for(;*from;)*to+=*from

40、+;*to=0;字符串合并函数:字符串合并函数:例T10-16.c,void append_string(char void append_string(char *from,char from,char *to)to)for(;for(;*to;to+);to;to+);for(;for(;*from;)from;)*to+=to+=*from+;from+;*to=0;to=0;阅读程序:阅读程序:例T10-17.cvoid f(char *c)main()c+=2;char c20=”abcdef”;(*c)+;f(c+1);c+;*c=0;printf(“%s”,c);内存空间的动态分

41、配内存空间的动态分配 在程序设计中,对于要处理的批量数据,在程序设计中,对于要处理的批量数据,我们往往是选用数组作为存放这些数据的数据我们往往是选用数组作为存放这些数据的数据结构,然而,数组有一个明显的缺点,就是在结构,然而,数组有一个明显的缺点,就是在定义数组时,其长度必须是常值,无法根据需定义数组时,其长度必须是常值,无法根据需要动态地定义。这样,在很多情况下,不是定要动态地定义。这样,在很多情况下,不是定义的数组长度不够,就是定义太长以至于浪费。义的数组长度不够,就是定义太长以至于浪费。采用动态分配可以克服这一缺点,并且可采用动态分配可以克服这一缺点,并且可以随时释放。以随时释放。动态分

42、配内存空间步骤:动态分配内存空间步骤:定义一指针变量。定义一指针变量。申请一片内存空间,并将其首地址赋给指针变量。申请一片内存空间,并将其首地址赋给指针变量。此时便可通过指针变量访问这片内存;不成功则返回地址此时便可通过指针变量访问这片内存;不成功则返回地址为为0 0 用完后释放这片内存空间。用完后释放这片内存空间。int int *p;p;p=p=mallocmalloc(字节数字节数););freefree(p);(p);sizeofsizeof(类型类型):):返回该类型数据在当前编译系统中所占的返回该类型数据在当前编译系统中所占的字节数。字节数。以上函数的原形在以上函数的原形在stdi

43、o.hstdio.h中中。p例:对例:对n n个学生的分数排序后输出。个学生的分数排序后输出。例T10-18.c#include#include “stdio.hstdio.h”void sort(int void sort(int *a,int n)a,int n)main()main()int int *a,j,n;a,j,n;scanf(scanf(“%d%d”,&n);,&n);a=a=mallocmalloc(n(n*sizeofsizeof(int);(int);if(!a)exit(0);if(!a)exit(0);for(j=0;jn;j+)scanf(for(j=0;jn;j

44、+)scanf(“%d%d”,a+j);,a+j);sort(a,n);sort(a,n);for(j=0;jn;j+)printf(for(j=0;jy)z=x;else z=y;return(z);main()int (*p)();定义指向函数的指针变量定义指向函数的指针变量p p int a,b,c;p=max;将将p p指向函数指向函数maxmax scanf(“%d%d”,&a,&b);c=(*p)(a,b);通过通过p p调用函数调用函数maxmax 等效于等效于c=max(a,b);c=max(a,b);printf(“n%d”,c);例T10-19.c把指向函数的指针变量作为函

45、数参数把指向函数的指针变量作为函数参数 指向函数的指针变量最常见的用途是把它指向函数的指针变量最常见的用途是把它作为函数的参数,用于接受主调函数传来的某作为函数的参数,用于接受主调函数传来的某一函数的入口地址,从而在被调函数中可以通一函数的入口地址,从而在被调函数中可以通过该指针变量调用它所指向的函数,这样,被过该指针变量调用它所指向的函数,这样,被调函数中就可实现非固定函数的调用,以达到调函数中就可实现非固定函数的调用,以达到编写通用函数的目的。编写通用函数的目的。例:用矩形法编写一个通用的求定积分的函数。例:用矩形法编写一个通用的求定积分的函数。关键问题:如何处理被积函数是未知的。关键问题

46、:如何处理被积函数是未知的。double intgral(double a,double b,int n,double intgral(double a,double b,int n,double (double (*f)()f)()int i;int i;double h,x,y,s=0;double h,x,y,s=0;h=(b-a)/n;h=(b-a)/n;for(i=1;i=n;i+)for(i=1;i=n;i+)x=a+(i-1)x=a+(i-1)*h;h;y=y=(*f)(x)f)(x);s+=h s+=h*y;y;return(s);return(s);例T10-20.cdoub

47、le f1(double x)return(3*x*x+2*x-1);main()double s;s=intgral(1.0,2.0,100,f1);10.8 指针型数据小结 一、有关指针的数据类型一、有关指针的数据类型(见下表)p是一个指针变量,它指向一个指向整型数据的指针变量int*pp为指向函数的指针,该函数返回一个整型值int(int(*p)()p)()p为一个函数,它返回一个指针,该指针指向一个整型数据int int*p()p()f为返回整型数据的函数int f()定义指针变量p,它指向一个含n个整型元素的一维数组int(*p)n定义指针数组p,它由n个指向整型数据的指针元素组成i

48、nt int*pnpn定义整型数组a,它有n个元素int an定义指向整型数据的指针变量pint*p定义整型变量iint i含义定义 二、指针运算小结二、指针运算小结 1、指针变量加减一个整数、指针变量加减一个整数如:p+p-p+i p-i p+=i p-=i 等实际含义如 p+i 代表地址计算:p+c*i,c为字节数,例如字符型c=1。2、指针变量赋值、指针变量赋值 如:p=&a a为变量,p为指针变量 p=array array为数组名 p=&arrayi p=max max为函数名 p1=p2 p2为指针变量注意:不能把一个整数或常数赋给p,如p=1000 同样也不能把p赋给整型变量,如

49、i=p 3、指针变量可以赋空值、指针变量可以赋空值如:p=NULL;实际NULL是整数0。4、两个指针变量可以相减、两个指针变量可以相减 如两个指针变量指向同一个数组的元素(如右图),则 p2-p1=4-1=3但p1+p2无意义。5、两个指针变量比较、两个指针变量比较 若两个指针指向同一个数组的元素,则可以比较,如:p1p2inv(int x,int n)int i,j,m,t;main()m=(n-1)/2;for(i=0;i=m;i+)int a10,i;输入输入a j=n-1-i;inv(a,10);t=xi;输出输出a xi=xj;xj=t;ax例例T10-6-1.c:将数组:将数组a

50、中的中的n个数按相反顺序存放。个数按相反顺序存放。a与x共用同一片内存单元inv(int *x,int n)指针变量作函数参数时的传递情况int i,j,m,t;main()m=(n-1)/2;for(i=0;i=m;i+)int a10,i;j=n-1-i;输入输入a t=xi;inv(a,10);xi=xj;输出输出a xj=t;下标法例T10-6-2.c a10001000 x j=n-1-i;t=*(x+i);*(x+i)=*(x+j);*(x+j)=t;指针法指针法例T10-6-3.c 进一步优化:进一步优化:例T10-6-4.c int inv(int *x,int n)main(

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

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(c语言程序设计》10-指针.ppt)为本站会员(晟晟文业)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|