第8章善于利用指针_第1页
第8章善于利用指针_第2页
第8章善于利用指针_第3页
第8章善于利用指针_第4页
第8章善于利用指针_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

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

文档简介

1、第八章第八章 善于利用指针善于利用指针n地址和指针的概念地址和指针的概念n变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量n数组与指针数组与指针n字符串与指针字符串与指针n指向函数的指针指向函数的指针n返回指针值的函数返回指针值的函数n指针数组和指向指针的指针指针数组和指向指针的指针n指针的数据类型和指针运算指针的数据类型和指针运算指针指针是语言中广泛使用的一种是语言中广泛使用的一种数据类型数据类型,运用指针编,运用指针编程是语言最主要的风格之一。程是语言最主要的风格之一。利用利用指针变量指针变量可以表示各种数据结构;能很方便地使用可以表示各种数据结构;能很方便地使用数组和字符串;

2、并能象汇编语言一样数组和字符串;并能象汇编语言一样处理内存地址处理内存地址,从而,从而编出精练而高效的程序。编出精练而高效的程序。指针极大地丰富了语言的功能。学习指针是学习语指针极大地丰富了语言的功能。学习指针是学习语言中言中最重要最重要的一环,能否正确理解和使用指针是我们是否的一环,能否正确理解和使用指针是我们是否掌握语言的一个标志。掌握语言的一个标志。指针是语言中指针是语言中最为困难最为困难的一部分,在学习中除了要正的一部分,在学习中除了要正确理解基本概念,还必须要确理解基本概念,还必须要多思考多思考、多比较多比较、多编程多编程,多多上机上机,在实践中掌握它。,在实践中掌握它。 通常把存放

3、数据的内存单元的地址称为通常把存放数据的内存单元的地址称为指针指针。在语言中,允许用一个变量来存放指针,这种变量称为在语言中,允许用一个变量来存放指针,这种变量称为指针指针变量变量。因此,一个指针变量的值就是某个内存单元的地。因此,一个指针变量的值就是某个内存单元的地即:即:一般变量用来存储变量的值;一般变量用来存储变量的值;指针变量指针变量是用来保存变量地是用来保存变量地址的变量;变量的地址又称址的变量;变量的地址又称变量的指针变量的指针,是一个常量。,是一个常量。定义指针变量的一般形式:定义指针变量的一般形式: 数据类型数据类型 * *指针变量名;指针变量名; 若有:若有:char cha

4、r * *pc; pc; v则称指针变量则称指针变量pcpc是是charchar型指针型指针 vpc=&c;pc=&c; / /* * & &取取c c的地址的地址 * */ /v则称指针变量则称指针变量pcpc指向变量指向变量c cv* *pcpc表示表示pcpc所指向的变量,即变量所指向的变量,即变量c cv一个指针变量只能指向一个指针变量只能指向同一个类型同一个类型的变量的变量1000 A 变 量c1001 2000 1000 变 量pc运算符运算符& & 取变量的地址取变量的地址 2 2* * 取指针变量(所指向)的内容取指针变量(所指向

5、)的内容 2 2 例:例: int i=3; int i=3; int int * *i_pointer=&i; i_pointer=&i; (注:不允许把一个数赋予指针变量注:不允许把一个数赋予指针变量) 下面两个语句作用相同:下面两个语句作用相同: i=5; i=5; * *i_pointer=5; i_pointer=5; 例:输入例:输入a a和和b b两个整数,按先大后小的顺序输出两个整数,按先大后小的顺序输出a a和和b b。 void main( ) void main( ) int int * *p1p1, ,* *p2p2, ,* *p p,a,b;,a,b;

6、 scanf(“%d,%d”,&a,&b); scanf(“%d,%d”,&a,&b); p1=&a; p2=&b;p1=&a; p2=&b; if(ab) p=p1; p1=p2; p2=p; if(ab) p=p1; p1=p2; p2=p; printf(“na=%d,b=%dnn”,a,b); printf(“na=%d,b=%dnn”,a,b); printf(“max=%d,min=%dn”, printf(“max=%d,min=%dn”,* *p1p1, ,* *p2p2);); 运行情况如下:运行情况如下: 5

7、5,9 9 a=5a=5,b=9b=9 max=9 max=9,min=5min=5例:用函数交换两个变量的值。例:用函数交换两个变量的值。 # #include include void main ( ) void main ( ) void swap(int void swap(int * *pxpx,int ,int * *pypy); ; int a, b; int a, b; a=5; b=10; a=5; b=10; printf (before swap a=%d, b=%dn, a, b); printf (before swap a=%d, b=%dn, a, b); swa

8、p( swap( &a&a, , &b&b ); ); / /* * 实参为变量实参为变量a a和和b b的地址的地址 * */ / printf (after swap a=%d, b=%dn, a, b); printf (after swap a=%d, b=%dn, a, b); void swap(int void swap(int * *pxpx,int ,int * *pypy) / /* * 形参为指向整型的指针形参为指向整型的指针 * */ / int temp; int temp; temp = temp = * *pxpx; ; / /*

9、* 将指针变量将指针变量pxpx的内容赋给变量的内容赋给变量temp temp * */ / * *pxpx = = * *pypy; ; / /* * 将指针将指针pypy的内容赋给指针的内容赋给指针pxpx的内容的内容 * */ / * *pypy = temp; = temp; / /* * 将变量将变量temptemp的值赋给指针的值赋给指针pypy的内容的内容 * */ / printf (in swap x=%d, y=%dn, printf (in swap x=%d, y=%dn, * *pxpx, , * *pypy); ); 为了使在函数中改变了的变量值能被为了使在函数中改

10、变了的变量值能被mainmain函数所用,应该函数所用,应该用指针变量作为函数参数用指针变量作为函数参数,在函数执行过程中使指针变量所,在函数执行过程中使指针变量所指向的变量值发生变化,函数调用结束后,这些变量值的变指向的变量值发生变化,函数调用结束后,这些变量值的变化依然保留下来。即化依然保留下来。即指针参数指针参数使得被调用函数能够访问和修使得被调用函数能够访问和修改主调函数中变量的值。改主调函数中变量的值。注意注意1 1:下面的写法有问题下面的写法有问题void swap(int void swap(int * *p1,int p1,int * *p2)p2)int int * *tem

11、p;temp; * *temp=temp=* *p1; p1; / /* *此语句有问题此语句有问题* */ / * *p1=p1=* *p2;p2; * *p2=p2=* *temp;temp; 注意注意2 2:不能企图通过改不能企图通过改变指针形参的值而使指针实变指针形参的值而使指针实参的值改变参的值改变voidvoid swap(int swap(int * *p1,int p1,int * *p2)p2) int int * *p;p; p=p1; p=p1; p1=p2; p1=p2; p2=p; p2=p; 例:例:输入输入a a、b b、c3c3个整数,按大小顺序输出。个整数,按

12、大小顺序输出。 void void swapswap(int (int * *pt1pt1,int ,int * *pt2pt2) ) int temp; int temp; temp= temp=* *pt1; pt1; * *pt1=pt1=* *pt2; pt2; * *pt2=temp;pt2=temp; void void exchangeexchange(int (int * *q1q1,int ,int * *q2q2,int ,int * *q3q3) ) if( if(* *q1q1* *q2) swap(q1,q2);q2) swap(q1,q2); if( if(* *q

13、1q1* *q3) swap(q1,q3);q3) swap(q1,q3); if( if(* *q2q2* *q3) swap(q2,q3);q3) swap(q2,q3); void main() void main() int a,b,c, int a,b,c,* *p1p1, ,* *p2p2, ,* *p3p3; ; scanf(“%d,%d,%d”,&a,&b,&c); scanf(“%d,%d,%d”,&a,&b,&c); p1=&a; p2=&b; p3=&c; p1=&a; p2=&b;

14、p3=&c; exchange(p1,p2,p3);exchange(p1,p2,p3); printf(“n%d,%d,%dn”,a,b,c); printf(“n%d,%d,%dn”,a,b,c); 在在C C语言中,指针和数组之间的关系十分密切,通过语言中,指针和数组之间的关系十分密切,通过数组下数组下标标所能完成的任何操作都可以通过所能完成的任何操作都可以通过指针指针来实现。一般,用指来实现。一般,用指针编写的程序执行速度快,但用指针实现的程序理解起来困针编写的程序执行速度快,但用指针实现的程序理解起来困难一些。难一些。定义一个定义一个指向数组元素指向数组元素的指针变量的方法,

15、与以前介绍的的指针变量的方法,与以前介绍的指针变量相同。指针变量相同。例如:例如:int a10int a10; int int * *p p; / /* *定义定义p p为指向整型变量的指针为指向整型变量的指针* */ / p=&a0;p=&a0; / /* *对指针变量赋值对指针变量赋值* */ /C C语言规定,语言规定,数组名数组名代表数组的首地址,也就是第代表数组的首地址,也就是第0 0号元素号元素的地址。因此,下面两个语句等价:的地址。因此,下面两个语句等价: p=&a0; p=a;p=&a0; p=a;在定义指针变量时可以赋给初值:在定义指针变量时

16、可以赋给初值:int int * *p=&a0; p=&a0; 等价于:等价于: int int * *p; p; p=&a0; p=&a0; 也可以写成:也可以写成: int int * *p=a;p=a;C C语言规定:如果指针变量语言规定:如果指针变量p p已指向数组中的一个元素,则已指向数组中的一个元素,则p+1p+1指向同一数组中的下一个元素。指向同一数组中的下一个元素。引入指针变量后,就可以用两种方法来访问数组元素了。引入指针变量后,就可以用两种方法来访问数组元素了。如果如果p p的初值为的初值为& &a0,a0,则:则:1 1)p+

17、ip+i和和a+ia+i就是就是aiai的地址,或者说它们指向的地址,或者说它们指向a a数组的第数组的第i i个元个元素素。2 2)* *( (p+i)p+i)或或* *( (a+i)a+i)就是就是p+ip+i或或a+ia+i所指向的数组元素,即所指向的数组元素,即aiai。例如,例如,* *( (p+5)p+5)或或* *( (a+5)a+5)就是就是a5a5。3 3)指向数组的指针变量也可以带下标,如指向数组的指针变量也可以带下标,如pipi与与* *( (p+i)p+i)等价。等价。因此,引用一个数组元素因此,引用一个数组元素可以用:可以用: 1 1)下标法下标法,即用,即用aiai

18、形式访形式访问数组元素。在前面介绍数问数组元素。在前面介绍数组时都是采用这种方法。组时都是采用这种方法。 2 2)指针法指针法,即采用,即采用* *( (a+i)a+i)或或* *( (p+i)p+i)形式,用间接访问的形式,用间接访问的方法来访问数组元素。方法来访问数组元素。注意:注意:指针变量可以实现指针变量可以实现本身的值的改变。如本身的值的改变。如p+p+是合是合法的;而法的;而a+a+是错误的。因为是错误的。因为a a是数组名,它是数组的首地是数组名,它是数组的首地址,是常量。址,是常量。 例:输入和输出数组中的全部元素例:输入和输出数组中的全部元素void main( )void

19、main( ) int a10,i; int a10,i; for(i=0;i10;i+) for(i=0;i10;i+) scanf(“%d”,&ai); scanf(“%d”,&ai); for(i=0;i10;i+) for(i=0;i10;i+) printf(“%d”,ai); printf(“%d”,ai); * *( (a+i)a+i)for(p=a;p(a+10);p+)for(p=a;p(a+10);p+) printf(“%d”, printf(“%d”,* *p);p);int int * *p;p;for(p=a;a(p+10);a+)for(p=a;a

20、(p+10);a+) printf(“%d”, printf(“%d”,* *a);a);注注意意void main( )void main( ) int a10,i int a10,i,* *p;p; p=a;p=a; for(i=0;i10;i+) for(i=0;i10;i+) scanf(“%d”,p+); scanf(“%d”,p+); p=a;p=a; for(i=0;i10;i+,p+) for(i=0;i10;i+,p+) printf(“%d”, printf(“%d”,* *p);p); 例:将数组例:将数组a a中中n n个整数按相反顺序存放。个整数按相反顺序存放。voi

21、d inv(void inv(int xint x,int n),int n)int temp,i,j,m=(n-1)/2;int temp,i,j,m=(n-1)/2; for(i=0;i=m;i+) for(i=0;i=m;i+) j=n-1-i; j=n-1-i; temp=xi;xi=xj;xj=temp; temp=xi;xi=xj;xj=temp; void main( )void main( )int i,a10=3,7,9,11,0,6,7,5,4,2;int i,a10=3,7,9,11,0,6,7,5,4,2; for(i=0;i10;i+) printf(%d,”,ai)

22、; for(i=0;i10;i+) printf(%d,”,ai); printf(“n”); printf(“n”); inv(a,10);inv(a,10); for(i=0;i10;i+) printf(“%d,”,ai); for(i=0;i10;i+) printf(“%d,”,ai); void inv(void inv(int int * *x x,int n),int n)int temp,m=(n-1)/2;int temp,m=(n-1)/2; int int * *p,p,* *i,i,* *j;j; i=x; j=x+n-1; p=x+m; i=x; j=x+n-1;

23、p=x+m; for(;i=p;i+,j-) for(;i=p;i+,j-) temp= temp=* *i;i;* *i=i=* *j;j; * *j=temp;j=temp; 归纳起来,如果有一个实参数组,想在函数中改变此数组的归纳起来,如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下元素的值,实参与形参的对应关系有以下4种情况:种情况:实参实参形参形参数组名数组名数组名数组名数组名数组名指针变量指针变量指针变量指针变量数组名数组名指针变量指针变量指针变量指针变量main()main() int a10; int a10; f(a,10); f(a,10);

24、f(int x,int n)f(int x,int n) f(int f(int * *x,int n)x,int n) main()main() int a10 int a10,* *p;p; p=a; p=a; f(p,10); f(p,10); f(int x,int n)f(int x,int n) f(int f(int * *x,int n)x,int n) 设有整型二维数组设有整型二维数组a34a34的定义为:的定义为:int a34=0,1,2,3,4,5,6,7,8,9,10,11int a34=0,1,2,3,4,5,6,7,8,9,10,11设数组设数组a a的首地址为的

25、首地址为10001000,各下标变量的首地址及其值如图,各下标变量的首地址及其值如图语言允许把一个二维数组分解为语言允许把一个二维数组分解为多个一维数组来处理。因此数组多个一维数组来处理。因此数组a a可分解为三个一维数组,即可分解为三个一维数组,即a0a0、a1a1、a2a2,每一个一维数组又含每一个一维数组又含有四个元素。有四个元素。 从二维数组的角度来看,从二维数组的角度来看,a a是二维数组名,是二维数组名,a a代表整个二维数组的首地址,也代表整个二维数组的首地址,也是二维数组是二维数组0 0行的首地址,等于行的首地址,等于10001000。a+1a+1代表第一行的首地址,等于代表第

26、一行的首地址,等于10081008。如图:如图: a a,a0a0,* *(a+0)(a+0),* *a a,&a00&a00是相等的,是相等的,同理,同理, a+1,a1,a+1,a1,* *(a+1),&a10(a+1),&a10是等同的。是等同的。由此可得出:由此可得出:a+ia+i,aiai,* *(a+i)(a+i),&ai0&ai0是等同的。此外,是等同的。此外,& &aiai和和aiai也是等同的。另外,也是等同的。另外,a0a0也可以看成是也可以看成是a0+0a0+0,是一维数组是一维数组a0a0的的0 0号元素的

27、首地址,而号元素的首地址,而a0+1a0+1则是则是a0a0的的1 1号元素首地址,由此可得出号元素首地址,由此可得出ai+jai+j则是一维数组则是一维数组aiai的的j j号元素首地址号元素首地址,它等于,它等于& &aijaij。由由ai=ai=* *(a+i)(a+i)得得ai+j=ai+j=* *(a+i)+j(a+i)+j。由于由于* *( (a+i)+ja+i)+j是二维数组是二维数组a a的的i i行行j j列元素的首地址,所以,该元素的值等于列元素的首地址,所以,该元素的值等于* *( (* *( (a+i)+j)a+i)+j)。 例例:已知已知 int a3

28、4=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; 求:求: A) A) * *(a+1)+2 (a+1)+2 B) B) * *(a0+6) (a0+6) C) C) * *(a1+2) (a1+2) D) D) * *(&a00+6)(&a00+6) E E)* *( (* *(a+1)+2)(a+1)+2)即即a12的地址的地址即即数组元素数组元素a12,等于等于7 即即数组元素数组元素a12,等于等于7即即数组元素数组元素a12,等于等于7即即数组元素数组元素a12,等于等于7例:用指针变量

29、输出数组元素的值例:用指针变量输出数组元素的值void main( )void main( )int a34=1,3,5,7,9,11,13,15,17,19,21,23;int a34=1,3,5,7,9,11,13,15,17,19,21,23; int int * *p;p; for(p=a0;pa0+12;p+) for(p=a0;pa0+12;p+) printf(“%4d”, printf(“%4d”,* *p);p); int i,j,int i,j,* *p; p; p=a0;p=a0;for(i=0;i3;i+)for(i=0;i3;i+) for(j=0;j4;j+) fo

30、r(j=0;j4;j+) printf(“%4d”,printf(“%4d”,* *(p+(p+i i* *m+jm+j););aijaij在数组中的相对位置在数组中的相对位置又称为又称为数组指针数组指针,其,其说明形式说明形式为为: 数据类型数据类型 ( ( * * 指针变量名指针变量名)常量表达式常量表达式 例如:例如:int (int (* *pa)6pa)6; 含义:定义了一个指向数组的指针,被指向的数组是一含义:定义了一个指向数组的指针,被指向的数组是一 个个有有6 6个元素的整型个元素的整型一维一维数组。数组。整数整数整数整数整数整数整数整数整数整数整数整数( (* *pa)0pa

31、)0( (* *pa)1pa)1( (* *pa)2pa)2( (* *pa)3pa)3( (* *pa)4pa)4( (* *pa)5pa)5papa注意:注意:pa+1pa+1将将指向下一个一指向下一个一维数组维数组pa+1pa+1例:输出二维数组任一行任一列元素的值例:输出二维数组任一行任一列元素的值void main( )void main( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23; int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (int (* *p)4p)4,i,j;,i,j; p=a;p=a; sc

32、anf(“i=%d,j=%d”,&i,&j); scanf(“i=%d,j=%d”,&i,&j); printf(“a%d,%d=%dn”,i,j, printf(“a%d,%d=%dn”,i,j,* *( (* *(p+i)+j)(p+i)+j);); 注意区分:注意区分:p+ip+i 和和 * *(p+ip+i) (p+ip+i)+j+j 和和 * *(p+ip+i)+j+j例如:例如:p+2 p+2 和和 * *(p+2p+2)具有相同的值,具有相同的值, 但但(p+2p+2)+3 +3 和和 * *(p+2p+2)+3 +3 的值就不相同的值就不相同在用

33、指针变量作形参以接受实参数组名传递来的地址时,有在用指针变量作形参以接受实参数组名传递来的地址时,有两种方法:两种方法:1 1)用指向变量的指针变量用指向变量的指针变量;2 2)用指向一维数组的用指向一维数组的指针变量指针变量例:有一个班,例:有一个班,3 3个学生,各个学生,各4 4门课,计算总平均分数,以及第门课,计算总平均分数,以及第n n个学生的成绩个学生的成绩#include#includevoid main( )void main( )void average(float void average(float * *p,int n)p,int n) void search(floa

34、t ( void search(float (* *p)4,int n);p)4,int n); float score34 float score34 =65,67,70,60,80,87,90,81,90,99,100,98; =65,67,70,60,80,87,90,81,90,99,100,98; average( average(* *scorescore,12);,12); search( search(scorescore,2);,2); void average(void average(float float * *p p,int n),int n)float float

35、* *p_end,aver,sum=0;p_end,aver,sum=0; p_end=p+n-1; p_end=p+n-1; for(;p=p_end;p+) sum=sum+( for(;p=p_end;p+) sum=sum+(* *p p);); aver=sum/n; aver=sum/n; printf(“average=%5.2fn”,aver); printf(“average=%5.2fn”,aver);void search(void search(float (float (* *p)4p)4,int n),int n)int i;int i; printf(“No.%d

36、 score are:n”,n); printf(“No.%d score are:n”,n); for(i=0;i4;i+) for(i=0;i4;i+) printf(“5.2f”, printf(“5.2f”,* *( (* *(p+n)+i)(p+n)+i););字符串的表示形式字符串的表示形式(1 1)用字符数组存放一个字符串,然后输出该字符串)用字符数组存放一个字符串,然后输出该字符串 void main( )void main( ) char stringchar string=“I love China!”;=“I love China!”; printf(“%sn”,stri

37、ng); printf(“%sn”,string); (2 2)用字符指针指向一个字符串用字符指针指向一个字符串 void main( )void main( ) char char * *stringstring=“I love China!”;=“I love China!”; printf(“%sn”,string); printf(“%sn”,string); char char * *stringstring;stringstring=“I love China!”;=“I love China!”;注意:注意:这里是把存放字符串的字这里是把存放字符串的字符数组的首地址赋给符数组的首

38、地址赋给stringstring,它它只能指向只能指向一个一个字符型数据字符型数据字符串指针变量字符串指针变量的定义说明与的定义说明与指向字符变量的指针变量指向字符变量的指针变量说明说明是相同的。只能按对指针变量的赋值不同来区别。对指向字符是相同的。只能按对指针变量的赋值不同来区别。对指向字符变量的指针变量应赋予该字符变量的地址。变量的指针变量应赋予该字符变量的地址。 如:如: char c,char c,* *p=&cp=&c; ;表示表示p p是一个指向字符变量是一个指向字符变量c c的指针变量。的指针变量。而:而: char char * *s=C Languages=C

39、 Language; ;则表示则表示s s是一个指向字符串的指针变量。把字符串的首地址赋是一个指向字符串的指针变量。把字符串的首地址赋予予s s。即即等等价价于:于: char char * *s;s; s=C Language; s=C Language;例:例: void void main( )main( ) char char * *ps=this is a book;ps=this is a book; ps=ps+10; ps=ps+10; printf(%sn,ps); printf(%sn,ps); 例:将字符串例:将字符串a a复制为字符串复制为字符串b b。void mai

40、n( )void main( )char a=“I am a boy.”,b20;char a=“I am a boy.”,b20; int i; int i; for(i=0; for(i=0;* *(a+i)!=0;i+)(a+i)!=0;i+) * *(b+i)=(b+i)=* *(a+i)(a+i); ; * *(b+i)=0;(b+i)=0; printf(“string a is:%sn”,a); printf(“string a is:%sn”,a); printf(“string b is:”); printf(“string b is:”); for(i=0;bi!=0;i+

41、) for(i=0;bi!=0;i+) printf(“%c”,bi); printf(“%c”,bi); printf(“n”); printf(“n”); void main( )void main( )char a=“I am a boy.”;char a=“I am a boy.”; char b20, char b20,* *p1,p1,* *p2;p2; int i; int i; p1=a; p2=b; p1=a; p2=b; for(; for(;* *p1!=0;p1!=0;p1+,p2+p1+,p2+) ) * *p2=p2=* *p1p1; ; * *p2=0;p2=0;

42、 printf(“string a printf(“string a is:%sn”,a); is:%sn”,a); printf(“string b is:”); printf(“string b is:”); for(i=0;bi!=0;i+) for(i=0;bi!=0;i+) printf(“%c”,bi); printf(“%c”,bi); printf(“n”); printf(“n”); 字符串指针作函数参数字符串指针作函数参数例:例:用函数调用实现用函数调用实现字符串字符串的的复制。复制。 void strcopy(char str1,char str2) /void strc

43、opy(char str1,char str2) /* *将将str1str1拷贝到拷贝到str2str2中中* */ / while(str1i!=0)while(str1i!=0) str2i=str1i; i+; str2i=str1i; i+; str2i=0; str2i=0; void main( ) void main( ) char a= char a=“I am a teacher.”;“I am a teacher.”; char b=“you are a student.” char b=“you are a student.” printf (a=%snb=%sn, a

44、, b ); printf (a=%snb=%sn, a, b ); strcopy ( a, b ); / strcopy ( a, b ); /* * 函数的实参为数组名函数的实参为数组名 * */ / printf (a=%snb=%sn, a, b ); printf (a=%snb=%sn, a, b ); * *a a* *b bvoid strcopy(char void strcopy(char * *str1,char str1,char * *str2)str2) while(while(* *str1!=0)str1!=0) * *str2=str2=* *str1; s

45、tr1; str1+; str2+; str1+; str2+; * *str2=0;str2=0; /调用函数调用函数f f,从字符串中删除所有的数字字符。,从字符串中删除所有的数字字符。#include #include #include #include #include #include void f(char void f(char * *s)s) int i=0; int i=0; while(si!=0) while(si!=0) if(isdigit(si) strcpy(s+i,s+i+1); if(isdigit(si) strcpy(s+i,s+i+1); else i+

46、; else i+; void main()void main() char str80; char str80; gets(str); f(str); puts(str); gets(str); f(str); puts(str); 字符串指针作函数参数字符串指针作函数参数n程序只有装入内存才能运行。在内存中也要给函数分配一程序只有装入内存才能运行。在内存中也要给函数分配一个入口地址个入口地址, , 因此通过定义一个指向该函数的指针因此通过定义一个指向该函数的指针, , 即可即可引用该函数。引用该函数。n指向函数的指针变量的定义形式为指向函数的指针变量的定义形式为: : 数据类型数据类型 (

47、 (* *指针变量名指针变量名)()(函数参数表列函数参数表列 ); ); n定义了指向函数的指针变量定义了指向函数的指针变量, ,并不表示指向哪个具体的函数并不表示指向哪个具体的函数, ,要想指向具体的函数要想指向具体的函数, ,还必须给它赋值。还必须给它赋值。n指向函数的指针赋值的一般格式指向函数的指针赋值的一般格式: : 指针变量名指针变量名= =函数名函数名; ;n例如例如: : int (int (* *p)(int,int),max(int,int);p)(int,int),max(int,int); p=max; p=max;n用函数指针变量调用函数用函数指针变量调用函数n指向函

48、数的指针赋值后指向函数的指针赋值后, ,即可引用即可引用, ,其一般格式为其一般格式为: : ( (* *指针变量名指针变量名)()(函数实参表函数实参表););n例如例如, ,求两个数的最大值求两个数的最大值: : int a,b,(int a,b,(* *p)(int,int),max(int,int),res;p)(int,int),max(int,int),res; p=max;p=max; / /* * 不能写成不能写成 p=max(a,b); p=max(a,b); * */ / . . res=(res=(* *p)(a,b);p)(a,b); / /* * 与与 res=max

49、(a,b);res=max(a,b); 等价等价 * */ /注意:注意:p是指向函数的指针变量,它只能指向函数的入口处而是指向函数的指针变量,它只能指向函数的入口处而不可能指向函数中间的某一条指令处,因此不能用不可能指向函数中间的某一条指令处,因此不能用*(p+1)来表示函数的下一条指令。在一个程序中,一个指针变量可以来表示函数的下一条指令。在一个程序中,一个指针变量可以先后指向不同的函数。对先后指向不同的函数。对p作作p+n、p+、p-等运算无意义。等运算无意义。void process(int x,int y,void process(int x,int y,int (int (* *f

50、un)(int,int)fun)(int,int),char ,char * *s)s) int res; int res; res= res=( (* *fun)(x,y)fun)(x,y); ; printf(“ %s %dn”,s,res); printf(“ %s %dn”,s,res); 用指向函数的指针做函数参数用指向函数的指针做函数参数int max( int x,int y)int max( int x,int y) return return(xy ? x : yxy ? x : y);int min( int x, int y)int min( int x, int y)

51、return return(xy ? x : yxy ? x : y);int add( int x, int y)int add( int x, int y) return return(x + yx + y); ; int mult( int x, int y )int mult( int x, int y ) return return(x x * * y y); ; void main( )void main( ) int a,b; int a,b; printf(“Enter a,b:”); printf(“Enter a,b:”); scanf(“%d%d”,&a,&

52、;b); scanf(“%d%d”,&a,&b); process( a,b, process( a,b,maxmax,“max=”);,“max=”); process( a,b, process( a,b,minmin,“min=”);,“min=”); process( a,b, process( a,b,addadd,“add=”);,“add=”); processprocess( a,b,( a,b,multmult,“mult=”);,“mult=”); 函数的返回值是一个指针函数的返回值是一个指针( (即地址即地址) )函数的定义形式函数的定义形式: : 函数类

53、型函数类型 * *函数名函数名( (参数列表参数列表) )例如例如: : char char * *strchr(char strchr(char * *str,char ch)str,char ch) while( while(* *str!=ch) str+;str!=ch) str+; return(str); return(str); void main( ) void main( ) char ch=o,a=“hello world!”, char ch=o,a=“hello world!”,* *p;p; p=strchr(a,ch); p=strchr(a,ch); printf

54、(“%c”, printf(“%c”,* *p);p); printf(“%s”,p); printf(“%s”,p); 比较:比较:nint int * *func( ); func( ); 返回地址的函数返回地址的函数 , ,说明了一个函数说明了一个函数, , 其返回值为指向整其返回值为指向整型的指针型的指针; ; nint (int (* *func)( );func)( ); 指向函数的指针指向函数的指针, , 说明了一个指向返说明了一个指向返回值为整型的函数回值为整型的函数的指针变量。的指针变量。 数组中的元素均为指针类型,称之为数组中的元素均为指针类型,称之为指针数组指针数组。 指

55、针数组说明的形式为:指针数组说明的形式为: 数据类型数据类型 * * 数组名数组名 常量表达式常量表达式 例如:例如: int int * * pa6; pa6; 含义:定义一个由含义:定义一个由6 6个指针变量构成的指针数组,数组个指针变量构成的指针数组,数组中的每个数组元素中的每个数组元素指针,都指向一个整数。指针,都指向一个整数。整数整数整数整数整数整数整数整数整数整数整数整数pa0pa1pa2pa3pa4pa5指针数组指针数组pa指针数组指针数组比较适合于用来指向若干个字符串,使字符串处理比较适合于用来指向若干个字符串,使字符串处理更加方便灵活更加方便灵活 例例:将若干字符串按字母顺序

56、(由小到大)输出。将若干字符串按字母顺序(由小到大)输出。void main( )void main( ) void sort(char void sort(char * *name,int n);name,int n); void print(char void print(char * *name,int n);name,int n); char char * *namename= “Follow me”, “BASIC”, “Great = “Follow me”, “BASIC”, “Great Wall”,Wall”, “ F O R T R A N ” , “ c o m p u

57、t e r “ F O R T R A N ” , “ c o m p u t e r design” ;design” ; int n=5; int n=5; sort( sort(namename,n); print(,n); print(namename,n); ,n); void sort(void sort(char char * *namename,int n),int n) char char * *temp; int i,j,k;temp; int i,j,k; for(i=0;in-1;i+) for(i=0;in-1;i+) k=i; k=i; for(j=i+1;jn;j

58、+) for(j=i+1;j0strcmp(namek,namej)0) k=j;) k=j; if(k!=i) if(k!=i) temp=namei; namei=namek; namek=temp; temp=namei; namei=namek; namek=temp; void print(void print(char char * *namename,int n),int n) int i;int i; for(i=0;in;i+) for(i=0;in;i+) printf(“%sn”,namei); printf(“%sn”,namei); n存放指针地址的变量称为存放指针地

59、址的变量称为“指针的指针指针的指针”。n定义形式为:定义形式为: 数据类型数据类型 * * *指针变量名指针变量名; ; n例如例如: : int x=5, int x=5, * *xp, xp, * * *xppxpp; ; xp = &x; xp = &x; xpp = &xp; xpp = &xp; printf(“%d ”,x ); printf(“%d ”,x ); / /* *直接访问直接访问* */ / printf(“%d ”, printf(“%d ”,* *xp ); xp ); / /* *单级间址访问单级间址访问* */ / printf(“%d ”, printf(“%d ”,* * *xppxpp ); ); / /* *二级间址访问二级间址访问* */ /例例: : void main( )void main( ) char char * *namename= “Follow me”, “BASIC”, “Great = “Follow me”, “BASIC”, “Great Wall”,Wall”, “ F O R T R A N ” , “ c o m p u t e r “ F O R T R A N ” , “ c o m p u

温馨提示

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

评论

0/150

提交评论