第十章 指针指针是C语言中广泛使用的一种数据类型 运用指针_第1页
第十章 指针指针是C语言中广泛使用的一种数据类型 运用指针_第2页
第十章 指针指针是C语言中广泛使用的一种数据类型 运用指针_第3页
第十章 指针指针是C语言中广泛使用的一种数据类型 运用指针_第4页
第十章 指针指针是C语言中广泛使用的一种数据类型 运用指针_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

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

文档简介

1、 指针是语言中广泛使用的一种数据类型。指针是语言中广泛使用的一种数据类型。 运用指针编程是运用指针编程是语言最主要的风格之一。利用指针变量可以表示各种数据结构;语言最主要的风格之一。利用指针变量可以表示各种数据结构; 能很方便地使用数组和字符串;能很方便地使用数组和字符串; 并能象汇编语言一样处理内存地并能象汇编语言一样处理内存地址,从而编出精练而高效的程序。指针极大地丰富了语言的功址,从而编出精练而高效的程序。指针极大地丰富了语言的功能。能。 学习指针是学习语言中最重要的一环,学习指针是学习语言中最重要的一环, 能否正确理解和使能否正确理解和使用指针是我们是否掌握语言的一个标志。同时,用指针

2、是我们是否掌握语言的一个标志。同时, 指针也是语指针也是语言中最为抽象的一部分,在学习中除了要正确理解基本概念,还言中最为抽象的一部分,在学习中除了要正确理解基本概念,还必须要多编程,上机调试。只要做到这些,指针也是不难掌握的。必须要多编程,上机调试。只要做到这些,指针也是不难掌握的。欲穷千里,更上层楼欲穷千里,更上层楼一、指针的基本概念一、指针的基本概念 在计算机中,所有的数据都是存放在存储器中的。在计算机中,所有的数据都是存放在存储器中的。 一般把一般把存储器中的一个字节称为一个内存单元,存储器中的一个字节称为一个内存单元, 不同的数据类型所占不同的数据类型所占用的内存单元数不等,如整型量

3、占用的内存单元数不等,如整型量占2 2个单元,字符量占个单元,字符量占1 1个单元个单元等。等。 为了正确地访问这些内存单元,为了正确地访问这些内存单元, 必须为每个内存单元编上必须为每个内存单元编上号。内存单元的编号叫做地址。通常把这个地址称为指针。号。内存单元的编号叫做地址。通常把这个地址称为指针。 内存单元的指针和内存单元的内容是两个不同的概念。内存单元的指针和内存单元的内容是两个不同的概念。 对于一个内存单元来说,单元的地址即为指针,对于一个内存单元来说,单元的地址即为指针, 其中存其中存放的数据才是该单元的内容。放的数据才是该单元的内容。 在语言中,在语言中, 允许用一个变量来存放指

4、针,这种变量称为允许用一个变量来存放指针,这种变量称为指针变量。指针变量。一个指针变量的值就是某个内存单元的地址或称为一个指针变量的值就是某个内存单元的地址或称为该内存单元的指针。该内存单元的指针。欲穷千里,更上层楼欲穷千里,更上层楼变量变量i (i=3;)i (i=3;)变量变量j变量变量k k200020022004 3 6 9 20003010变量变量i_pointer(i_pointer(指针变量指针变量) ) i_pointer=&i; i_pointer=&i; 指针指针i_pointer i_pointer 指向变量指向变量i i内存单元地址与内存单元内容:内存单

5、元地址与内存单元内容:欲穷千里,更上层楼欲穷千里,更上层楼二、指针变量的定义和使用二、指针变量的定义和使用1、类型说明、类型说明 其一般形式为:其一般形式为: 类型说明符类型说明符 *变量名;变量名; 其中,其中,*表示这是一个指针变量,变量名即为定义的指针变量名,表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量将来可指向的变量的数据类型。例如:类型说明符表示本指针变量将来可指向的变量的数据类型。例如: int *p1;表示表示p1是一个指针变量,它的值将是某个整型变量的地址。是一个指针变量,它的值将是某个整型变量的地址。 或者或者说说p1将指向一个整型变量。至于将指

6、向一个整型变量。至于p1究竟指向哪一个整型变量,究竟指向哪一个整型变量, 应应由向由向p1赋予的地址来决定。赋予的地址来决定。欲穷千里,更上层楼欲穷千里,更上层楼再如:再如: static int *p2; /*p2是指向静态整型变量的指针变量是指向静态整型变量的指针变量*/ float *p3; /*p3是指向浮点变量的指针变量是指向浮点变量的指针变量*/ char *p4; /*p4是指向字符变量的指针变量是指向字符变量的指针变量*/ 应该注意的是,一个指针变量只能指向同类型的变量,如应该注意的是,一个指针变量只能指向同类型的变量,如P3 只只能指向浮点变量,不能时而指向一个浮点变量,能指

7、向浮点变量,不能时而指向一个浮点变量, 时而又指向一个字时而又指向一个字符变量。符变量。欲穷千里,更上层楼欲穷千里,更上层楼2、指针变量的赋值、指针变量的赋值 指针变量的赋值只能赋予地址,在语言中,指针变量的赋值只能赋予地址,在语言中, 变量的地址是由变量的地址是由编译系统分配的,用户不知道变量的具体地址。编译系统分配的,用户不知道变量的具体地址。 因此,语言因此,语言中提供了地址运算符中提供了地址运算符&来表示变量的地址。其一般形式为:来表示变量的地址。其一般形式为: & 变量名;变量名; 如如&a变示变量变示变量a的地址,的地址,&b表示变量表示变量b的地址

8、。的地址。 设有指向整型变量的指针变量设有指向整型变量的指针变量p,如要把整型变量,如要把整型变量a 的地址的地址赋予赋予p可以有以下两种方式:可以有以下两种方式:欲穷千里,更上层楼欲穷千里,更上层楼(1)指针变量初始化的方法指针变量初始化的方法 int a; int *p=&a;(2)赋值语句的方法赋值语句的方法 int a; int *p; p=&a; 不允许把一个数值赋予指针变量,故下面的赋值是错误的:不允许把一个数值赋予指针变量,故下面的赋值是错误的: int *p; p=1000; 被赋值的指针变量前不能再加被赋值的指针变量前不能再加“*”说明符,如写为说明符,如写为

9、*p=&a 也是也是错误的。错误的。欲穷千里,更上层楼欲穷千里,更上层楼3、指针变量的引用、指针变量的引用 两个两个指针运算符:指针运算符: (1)取地址运算符:取地址运算符:& (2)取内容运算符:取内容运算符:* 例如:例如: &a为变量为变量a的地址,的地址,*p为指针变量为指针变量p所指向的变所指向的变量量 #include ”stdio.h”#include “conio.h”main( ) int a=5,*p=&a; printf (%d,*p); getch( ); /*表示指针变量表示指针变量p取得了整型变量取得了整型变量a的地址的地址*/*本

10、语句表示输出变量本语句表示输出变量a的值。的值。*/ 欲穷千里,更上层楼欲穷千里,更上层楼输入输入a和和b两个整数,按大小顺序输出两个整数,按大小顺序输出a和和b#include ”stdio.h#include ”stdio.h”#include “conio.h#include “conio.h”main( ) int *p1,*p2,*p,a,b; scanf(%d,%d,&a,&b); p1=&a;p2=&b; if (ab) p=p1;p1=p2;p2=p; printf(na=%d,b=%dnn,a,b); printf(max=%d,min=%dn

11、,*p1,*p2); getch(); 输入:输入: 5,9 输出:输出:a=5,b=9 max=9,min=5 pp1ap2bpp1p2ab&a &b59&b&a59欲穷千里,更上层楼欲穷千里,更上层楼欲穷千里,更上层楼欲穷千里,更上层楼4、指针变量作为函数参数、指针变量作为函数参数 函数的参数不仅可以是整型、浮点型、字符型等数据,还可函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将以是指针类型。它的作用是将 一个变量的地址传送到另一个函一个变量的地址传送到另一个函数中,达到在该被调函数中对主调函数中的变量操作的目的。数中,达到在

12、该被调函数中对主调函数中的变量操作的目的。 #include ”stdio.h”#include “conio.h”main( ) void swap(int *p1,int *p2) void swap(int *p1,int *p2); int a,b; int temp; int *pointer1=&a,*pointer2=&b; temp=*p1; scanf(“%d%d”,&a,&b); *p1=*p2; if(ab) swap(pointer1,pointer2); *p2=temp; getch( ); 三、数组指针变量三、数组指针变量 指向数组

13、的指针变量称为数组指针变量。指向数组的指针变量称为数组指针变量。 一个数组是由连续的一块内存单元组成的。数组名就是这块连一个数组是由连续的一块内存单元组成的。数组名就是这块连续内存单元的首地址。续内存单元的首地址。 一个指针变量既可以指向一个数组,也可以指向一个数组元素。一个指针变量既可以指向一个数组,也可以指向一个数组元素。 数组的指针是指数组的起始地址。可把数组名或第一个元素的数组的指针是指数组的起始地址。可把数组名或第一个元素的地址赋予它。地址赋予它。 数组元素的指针是数组元素的地址。如要使指针变量指向第数组元素的指针是数组元素的地址。如要使指针变量指向第i元素可以把第元素可以把第i数组

14、元素的地址赋予它或把数组名加数组元素的地址赋予它或把数组名加i赋予它。赋予它。 欲穷千里,更上层楼欲穷千里,更上层楼1、数组指针变量的说明和使用、数组指针变量的说明和使用 1)数组指针变量的定义)数组指针变量的定义 指向数组的指针变量和指向普通变量的指针变量的说明是指向数组的指针变量和指向普通变量的指针变量的说明是相同的,如:相同的,如: int a10; int *p; 经过赋值语句经过赋值语句 p=&a0; 后后p指向数组指向数组a。 p=&a0; p=a; 等价。等价。欲穷千里,更上层楼欲穷千里,更上层楼p&a0a0a9a1a a数组数组从下图中我们可以看出有以下

15、关系:从下图中我们可以看出有以下关系:欲穷千里,更上层楼欲穷千里,更上层楼2)数组指针变量的使用)数组指针变量的使用 假设假设p为指针变量,且执行了:为指针变量,且执行了: p=&a2; 则则 *p=1; 表示对数组元素表示对数组元素a2赋以值赋以值1 C规定规定p+1指向下一个元素指向下一个元素(实际含义为实际含义为p+1*d,d为一个数组元素为一个数组元素 所占字节数)所占字节数) 如果如果p的初值为的初值为&a0,则:,则: p+i和和a+i就是就是ai的地址,或者说它们指向的地址,或者说它们指向a数组的第数组的第i元素元素 *(p+i) 或或*(a+i)是是p+i或或a

16、+i所指向的数组元素,即所指向的数组元素,即ai。 欲穷千里,更上层楼欲穷千里,更上层楼pa0a9a1a a数组数组p,a,&a0均指向同一单均指向同一单元,它们是数组元,它们是数组a的首地的首地址,也是第址,也是第0 元素元素a0的的地址。地址。 p+1,a+1,&a1均指向均指向第第1元素元素a1。类推可知。类推可知p+i,a+i,&ai指向第指向第i元素元素ai。 应该说明的应该说明的p是变量,是变量,而而a,&ai都是常量。在都是常量。在编程时应予以注意。编程时应予以注意。p+1,a+1p+i,a+i*(p+i)aip+9,a+9欲穷千里,更上层楼欲穷千

17、里,更上层楼 下标法下标法#include ”stdio.h#include ”stdio.h”#include “conio.h#include “conio.h”main( )main( ) int a10,i; int a10,i; for(i=0;i10;i+) for(i=0;i10;i+) ai=i; ai=i; printf(%d printf(%d,ai);ai); printf(n); printf(n); /*主函数主函数*/*分别分别定义一个整型数组和变量定义一个整型数组和变量*/*循环语句循环语句*/*给数组赋值给数组赋值*/*打印每一个数组的值打印每一个数组的值*/*

18、输出换行输出换行*/ 输出数组的输出数组的10个元素个元素欲穷千里,更上层楼欲穷千里,更上层楼 通过数组名计算数组元素通过数组名计算数组元素地址,找出元素的值地址,找出元素的值. .#include ”stdio.h#include ”stdio.h”#include “conio.h#include “conio.h”main( )main( ) int int a10,i; a10,i; for(i for(i=0;i10;i+)=0;i10;i+) * *(a+i)=i;(a+i)=i; printf(%d printf(%d ,* *(a+i);(a+i); printf(n prin

19、tf(n);); getch getch();(); /*主函数主函数*/*分别分别定义一个整型数组和变量定义一个整型数组和变量*/*循环语句循环语句*/*给数组赋值给数组赋值*/*打印每一个数组的值打印每一个数组的值*/*输出换行输出换行*/欲穷千里,更上层楼欲穷千里,更上层楼 用指针变量指向数组元素用指针变量指向数组元素#include ”stdio.h#include ”stdio.h”#include “conio.h#include “conio.h”mainmain( )( ) int int a10,i; a10,i; int int * *p; p; for(p=a;p(a+1

20、0);p+) for(p=a;p(a+10);p+) * *p=i;p=i; printf(%d printf(%d ,* *p);p); printf(n printf(n););getchgetch();(); /*主函数主函数*/ /* *分别定义一个整型数组和变量分别定义一个整型数组和变量* */ / /* *定义指针变量定义指针变量* */ / / /* *循环语句循环语句* */ /*给数组赋值给数组赋值*/*打印每一个数组的值打印每一个数组的值*/*输出换行输出换行*/欲穷千里,更上层楼欲穷千里,更上层楼2、数组名和数组指针变量作函数参数、数组名和数组指针变量作函数参数 在第七章

21、中曾经介绍过用数组名作函数的实参和形参的问题。在第七章中曾经介绍过用数组名作函数的实参和形参的问题。在学习指针变量之后就更容易理解这个问题了。在学习指针变量之后就更容易理解这个问题了。 数组名就是数组的首地址,实参向形参传送数组名实际上就是数组名就是数组的首地址,实参向形参传送数组名实际上就是传送数组的地址,传送数组的地址, 形参得到该地址后也指向同一数组。形参得到该地址后也指向同一数组。 这就好象这就好象同一件物品有两个彼此不同的名称一样。同一件物品有两个彼此不同的名称一样。 同样,指针变量的值也是地址,同样,指针变量的值也是地址, 数组指针变量的值即为数组的数组指针变量的值即为数组的首地址

22、,当然也可作为函数的参数使用。首地址,当然也可作为函数的参数使用。 例如:例如:欲穷千里,更上层楼欲穷千里,更上层楼数组名作函数的形参和实参时:数组名作函数的形参和实参时: main( ) int array10; f(array,10); f(int arr , int n) arrayarrarray0arr0.欲穷千里,更上层楼欲穷千里,更上层楼 实参用数组名,形参用指针变量实参用数组名,形参用指针变量 main( ) int array10; f(array,10); f(int *x,int n) array array0 x.欲穷千里,更上层楼欲穷千里,更上层楼 实参形参都用指针变

23、量实参形参都用指针变量 main( ) int array10,*p; p=array; f(p,10); f(int *x,int n) array0 x p.欲穷千里,更上层楼欲穷千里,更上层楼 实参用指针变量,形参用数组名实参用指针变量,形参用数组名 main( ) int array10,*p; p=array; f(p,10); f(int x,int n) array0 px0a9array9.欲穷千里,更上层楼欲穷千里,更上层楼欲穷千里,更上层楼欲穷千里,更上层楼四、指向多维数组的指针和指针变量四、指向多维数组的指针和指针变量1、多维数组的地址、多维数组的地址 例:例: int

24、a34=1,2,3,4,5,6,7,8,9,10,11,12; 说明:说明: 1)a是二维数组名。是二维数组名。 2)a数组包含数组包含3行,即行,即3个元素:个元素:a0,a1,a2。 3)a0,a1,a2又分别是一个一维数组。各包含又分别是一个一维数组。各包含4个个元素。如元素。如a0包含包含 a0 0,a 01,a 02,a 03。 从二维数组的角度看,从二维数组的角度看,a代表整个二维数组的首地址,代表整个二维数组的首地址,a+0代表二维数组代表二维数组a的第的第0元素,元素,a+1代表二维数组的第代表二维数组的第1元素。元素。同理,同理,a+2代表二维数组的第代表二维数组的第2元素。

25、元素。 假设假设a数组的首地址为数组的首地址为2000,则,则a+1为为2008。即:。即:2000+1*2*4(2为为int变量字节数,变量字节数,4为二维数组每个元素本身为二维数组每个元素本身又包含的元素数);同理,又包含的元素数);同理,a+2为为2016。 欲穷千里,更上层楼欲穷千里,更上层楼 a0,a1,a2既然是一维数组名,而既然是一维数组名,而C语言规定数组名代语言规定数组名代表数组的地址,因此,表数组的地址,因此, a0代表第代表第0行一维数组中第行一维数组中第0列元素的地列元素的地址,即址,即&a00。a1的值是的值是&a10,a2的值是的值是&a20

26、 。 2、多维数组元素的表示方法、多维数组元素的表示方法 1)表示元素)表示元素aij的地址:的地址: &aij /*取地址运算取地址运算*/ ai+j /*指针方法指针方法*/ 2)在讲述一维数组时候我们曾经提到:)在讲述一维数组时候我们曾经提到: 因为:因为: ai和和*(a+i) 等价!等价! 所以:所以: ai+j= =*(a+i)+j= =&aij 又因为:又因为: ai+j 是是aij的地址的地址 所以:所以: *( ai+j )aij 等价代换:等价代换:*(ai+j)= =*(*(a+i)+j)= =aij 欲穷千里,更上层楼欲穷千里,更上层楼3)进一步说明)进

27、一步说明ai的性质的性质 ai从形式上看是从形式上看是a数组中的第数组中的第i元素。元素。 如果如果a是一维数组名,则是一维数组名,则ai代表代表a数组第数组第i元素所占的内元素所占的内存单元。存单元。 ai是有物理地址的,是占内存单元的。是有物理地址的,是占内存单元的。 但如果但如果a是二维数组名,则是二维数组名,则ai代表一维数组名,代表一维数组名, ai本本身并不占实际的内存单元,也不存放身并不占实际的内存单元,也不存放a数组中各个元素。它数组中各个元素。它只是一个地址。只是一个地址。 故:故: a、a+i、 ai、 *(a+i) 、 *(a+i)+j都是地址。都是地址。 但是:但是:

28、a、a+i是行指针,指向二维数组的相应行!是行指针,指向二维数组的相应行! ai、 *(a+i) 、 *(a+i)+j是列指针,指向二维数组是列指针,指向二维数组的相应列!的相应列!欲穷千里,更上层楼欲穷千里,更上层楼3、指向多维数组的指针变量、指向多维数组的指针变量 (1)指向数组元素的指针变量)指向数组元素的指针变量 例如:例如: #inlcude “stdio.h” #include “conio.h” main( ) int a34=1,2,3,4,5,6,7,8,9,10,11,12,*p; for(p=a0;pa0+12;p+) if(p-a0%4=0) printf(“n”);

29、printf(“%4d”,*p); getch( ); 欲穷千里,更上层楼欲穷千里,更上层楼 (2)指向由)指向由m个元素组成的一维数组的指针变量个元素组成的一维数组的指针变量 例如:例如: #include “stdio.h” #include “conio.h” main( ) int a34=1,2,3,4,5,6,7,8,9,10,11,12,(*p)4,i,j; p=a; printf(“Please tell me the line and col numbers:”); scanf(“%d%d”,&i,&j); printf(“a%d%d=%dn”,i,j,*(*

30、(p+i)+j); getch(); (*p)4表示表示p是一个指针变量,它指向包含是一个指针变量,它指向包含4各元素的一维各元素的一维数组。数组。欲穷千里,更上层楼欲穷千里,更上层楼4、多维数组的指针作函数参数、多维数组的指针作函数参数 在用指针变量作形参以接受实参数组名传递过来的地址时,在用指针变量作形参以接受实参数组名传递过来的地址时,有两种方法:有两种方法: 1)用指向变量的指针变量。)用指向变量的指针变量。 2)用指向一维数组的指针变量。)用指向一维数组的指针变量。 例如:有一个班,例如:有一个班,3个学生,各学个学生,各学4门课,计算总平均分,门课,计算总平均分,以及第以及第2学生

31、的成绩。学生的成绩。 本程序用本程序用average求总平均成绩,用函数求总平均成绩,用函数search找出并输出第找出并输出第2学生的成绩。学生的成绩。欲穷千里,更上层楼欲穷千里,更上层楼#include “stdio.h”#include “conio.h”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,9890,99,100,98; average(*score,12); search(score,2)

32、; getch( );void search(float (*p)4,int n) int i; printf(“the score of No.%d are:”,n); for(i=0;i4;i+) printf(“%5.2f”,*(*(p+n)+i);void average(float void average(float * *p,intp,int n) n) float float * *p_end,sump_end,sum=0,aver;=0,aver; p_end p_end=p+n-1;=p+n-1; for(;p=p_end;p for(;p=p_end;p+)+) sum+

33、=( sum+=(* *p);p); aver=sum/n; aver=sum/n; printf(“averprintf(“aver=%5.2fn”,aver);=%5.2fn”,aver);五、字符串指针变量的说明和使用五、字符串指针变量的说明和使用1、字符串指针变量的说明、字符串指针变量的说明 字符串指针变量的定义说明与指向字符变量的指针变量说明是字符串指针变量的定义说明与指向字符变量的指针变量说明是相同的。如:相同的。如: char c,*p=&c;表示表示p是一个指向字符变量是一个指向字符变量c的指针变量。而:的指针变量。而: char *s=C Language;则表示则表

34、示s是一个指向字符串的指针变量。把字符串的首地址赋予是一个指向字符串的指针变量。把字符串的首地址赋予s。 欲穷千里,更上层楼欲穷千里,更上层楼2 2、字符串的表示形式、字符串的表示形式 1) 1) 字符数组字符数组 main()main() char a=C Language; char a=C Language; printf(%s,a printf(%s,a);); 2) 2) 字符指针字符指针 main()main() char char * *psps=C Language;=C Language; printf(%s,ps printf(%s,ps);); psa0a1a10 .欲穷

35、千里,更上层楼欲穷千里,更上层楼输出字符串中输出字符串中n个字符后的所有字符。个字符后的所有字符。#include “stdio.h#include “stdio.h”#include “conio.h#include “conio.h”main( ) char *ps=“THIS IS A BOOK; int n=10; ps=ps+n; printf(%sn,ps); getch(); 运行结果为:运行结果为: BOOK 在程序中对在程序中对ps初始化时,即把字符串首地址赋予初始化时,即把字符串首地址赋予ps,当,当ps= ps+10之后,之后,ps指向字符指向字符“B”,因此输出为,因此

36、输出为“BOOK。psps=ps+10欲穷千里,更上层楼欲穷千里,更上层楼对字符串中字符的存取可以用下标法也可以用指针法对字符串中字符的存取可以用下标法也可以用指针法例:将字符串例:将字符串a复制到复制到b #include “stdio.h” #include “conio.h” main( ) char a =I am a boy.,b20; int i; for (i=0;*(a+i)!=0;i+) for (i=0;ai!=0;i+) *(b+i)=*(a+i); bi=ai; *(b+i)=0; bi=0; printf(string a is :%sn,a); printf(str

37、ing b is :); for (i=0;bi!=0;i+) printf(%c,bi); getch(); 程序运行结果为:程序运行结果为:string a is : I am a boy.string b is : I am a boy.欲穷千里,更上层楼欲穷千里,更上层楼例:将字符串例:将字符串a复制到复制到b #include “stdio.h #include “stdio.h” #include “conio.h #include “conio.h” main( ) char a =I am a boy.,b20,*p1,*p2; int i; p1=a;p2=b; for (;

38、*p1!=0;p1+,p2+) *p2=*p1; *p2=0; printf(string a is :%sn,a); printf(string b is :); for (i=0;bi!=0;i+) printf(%c,bi); printf(n); getch(); a bp1p2欲穷千里,更上层楼欲穷千里,更上层楼欲穷千里,更上层楼欲穷千里,更上层楼3、字符串指针作函数参数、字符串指针作函数参数 将一个字符串从一个函数传递到另一个函数,可以用地址将一个字符串从一个函数传递到另一个函数,可以用地址传递的方法,即用字符数组名作参数或用指向字符串的指针变传递的方法,即用字符数组名作参数或用指

39、向字符串的指针变量作参数。在被调用函数中可以改变字符串的内容,在主调函量作参数。在被调用函数中可以改变字符串的内容,在主调函数中可以得到改变了的字符串。数中可以得到改变了的字符串。例如:例如: 例:用函数调用实现字符串的复制。例:用函数调用实现字符串的复制。 欲穷千里,更上层楼欲穷千里,更上层楼#include “stdio.h”#include “conio.h”void copy_string(char *from ,char *to) for(;*from!=0;from+,to+) *to=*from; *to=0;main( ) char *a=“I M a teacher!”; c

40、har *b=“U R a student!”; printf(“nstring a=%snstring b=%sn”,a,b); copy_string(a,b); printf(“nstring a=%snsting b=%sn”,a,b); getch(); 欲穷千里,更上层楼欲穷千里,更上层楼4 4、对使用字符指针变量和字符数组的讨论、对使用字符指针变量和字符数组的讨论 (1 1)数据结构不同。)数据结构不同。 (2 2)动态赋值方式不同。)动态赋值方式不同。 (3 3)赋初值方式不同。)赋初值方式不同。 (4 4)内存分配方式不同。)内存分配方式不同。 (5 5)指针变量的值可以改变

41、。)指针变量的值可以改变。 (6 6)用指针变量可以指向一个字符串。)用指针变量可以指向一个字符串。欲穷千里,更上层楼欲穷千里,更上层楼六、函数的指针和指向函数的指针变量六、函数的指针和指向函数的指针变量1、用函数指针变量调用函数、用函数指针变量调用函数 可以用指针变量指向整形变量、字符串、数组,也可以指向可以用指针变量指向整形变量、字符串、数组,也可以指向一个函数。一个函数。 一个函数在编译时被分配给一个入口地址,这个入口地址就一个函数在编译时被分配给一个入口地址,这个入口地址就称为函数的指针。称为函数的指针。 可以用一个指针变量指向函数,然后通过该指针变量调用此可以用一个指针变量指向函数,

42、然后通过该指针变量调用此函数。函数。欲穷千里,更上层楼欲穷千里,更上层楼例如:求例如:求a和和b中的大者。中的大者。#include main( ) int max(int ,int ); int (*p)( ), a,b,c; p=max; scanf(“%d%d”,&a,&b); c=(*p)(a,b); printf(“a=%d,b=%d,max=%d”,a,b,c);max(int x,int y) int z; if(xy) z=x; else z=y; return (z);int (*p)( )定义定义p是一个指向函是一个指向函数的指针变量,此函数带回整数的指针变

43、量,此函数带回整型的返回值。型的返回值。赋值语句赋值语句p=max;的作用是将函的作用是将函数数max的入口地址赋给指针变的入口地址赋给指针变量量p。(函数名代表该函数的入。(函数名代表该函数的入口地址)口地址)C=(*p)(a,b);用指针的形式实现用指针的形式实现函数的调用,相当于函数的调用,相当于C=max(a,b);欲穷千里,更上层楼欲穷千里,更上层楼说明:说明:1)指向函数的)指向函数的 指针变量的一般定义形式为指针变量的一般定义形式为 数据类型(数据类型(* 指针变量名)();指针变量名)();/*函数返回值类型函数返回值类型*/2)函数调用可以通过函数名调用,也可以通过函数指针调

44、用。)函数调用可以通过函数名调用,也可以通过函数指针调用。3)()(*p)()表示定义一个指向函数的指针变量,它是专门用来)()表示定义一个指向函数的指针变量,它是专门用来存放函数的入口地址的。在一个程序中,一个指针变量可以先后指存放函数的入口地址的。在一个程序中,一个指针变量可以先后指向不同的函数。向不同的函数。4)在给函数指针变量赋值时,只需给出函数名而不必给出参数。)在给函数指针变量赋值时,只需给出函数名而不必给出参数。5)用函数指针变量调用函数时,只需将()用函数指针变量调用函数时,只需将(*p)代替函数名,在)代替函数名,在 (*p)之后的括弧中根据需要写上实参。)之后的括弧中根据需

45、要写上实参。6)对指向函数的指针变量,)对指向函数的指针变量,p+、p+n、 p等运算是无意义的。等运算是无意义的。欲穷千里,更上层楼欲穷千里,更上层楼2、用指向函数的指针作函数参数、用指向函数的指针作函数参数 指向函数的指针也可以作为参数,以便实现函数地址的传递,指向函数的指针也可以作为参数,以便实现函数地址的传递,也就是将函数名传给形参。也就是将函数名传给形参。 原理:原理: 有一个函数有一个函数subsub,它有两个形参,它有两个形参x1x1和和x2x2:指向函数的指:指向函数的指针变量。在调用针变量。在调用subsub时,实参是两个函数名时,实参是两个函数名f1,f2f1,f2,给形参

46、传递函,给形参传递函数地址。从而实现在数地址。从而实现在函数函数subsub中调用中调用f1f1和和f2f2两个函数。两个函数。 例:输入例:输入a a和和b b两个数,设一个函数两个数,设一个函数processprocess,在调用它时,在调用它时,每次实现不同的功能:第一次调用每次实现不同的功能:第一次调用processprocess时找出时找出a a和和b b中大者,第中大者,第二次找出其中小者,第三次求二次找出其中小者,第三次求a a与与b b之和。之和。欲穷千里,更上层楼欲穷千里,更上层楼#include “stdio.h#include “stdio.h”#include “con

47、io.h#include “conio.h” ” int max(int,int int max(int,int);); int min(int,int int min(int,int);); int add(int,int int add(int,int);); int a,b int a,b; ; printf(“enter a&b printf(“enter a&b:”);:”); scanf(“%d%d”,&a,&b scanf(“%d%d”,&a,&b);); printf(“max printf(“max=“);=“); proces

48、s(a,b,max process(a,b,max);); printf(“minprintf(“min=“);=“); process(a,b,min process(a,b,min);); printf(“sumprintf(“sum=“);=“); process(a,b,add process(a,b,add);); getch getch();(); max(int x,intmax(int x,int y) y) return (xy)?x:y return (xy)?x:y;min(int x,intmin(int x,int y) y) return (xy)?x:y retu

49、rn (xy)?x:y;add(int x,intadd(int x,int y) y) return (x+y return (x+y););process(int x,int y,(process(int x,int y,(* *fun)(int intfun)(int int) ) int int result; result; result=( result=(* *fun)(x,yfun)(x,y);); printf(“%dn”,result printf(“%dn”,result);); 欲穷千里,更上层楼欲穷千里,更上层楼七、返回指针值的函数七、返回指针值的函数 一个函数可以带

50、回一个整型值、字符值、实型值等,也可以一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。带回指针型的数据,即地址。 带回指针值的函数,一般定义形式为:带回指针值的函数,一般定义形式为: 类型名类型名 * *函数名(参数表);函数名(参数表); int int * *a(int x, inta(int x, int y); y); 其中,其中,a a是函数名,调用它以后得到一个指向整型数据的指是函数名,调用它以后得到一个指向整型数据的指针。针。x,yx,y是函数是函数a a的形参,为整型。的形参,为整型。 例如:有若干个学生的成绩(每个学生有例如:有若干个学生的成绩(

51、每个学生有4 4门课),要求在门课),要求在用户输入学生学号以后,能输出该学生的全部成绩。用指针函数用户输入学生学号以后,能输出该学生的全部成绩。用指针函数实现。实现。欲穷千里,更上层楼欲穷千里,更上层楼#include “stdio.h#include “stdio.h”#include “conio.h#include “conio.h” ” float score4=60,70,80,90,56,89,67,88,34,78,90,66;float score4=60,70,80,90,56,89,67,88,34,78,90,66; float float * *search(floa

52、tsearch(float ( (* *pointer)4,int n);pointer)4,int n); float float * *p;int i,mp;int i,m; ; printf(“Enter the number of student:”); printf(“Enter the number of student:”); scanf(“%d”,&mscanf(“%d”,&m);); p=search(score,m p=search(score,m);); printf(“The score of NO.%d are:”,m printf(“The score of NO.%d are:”,m);); for(i for(i=0;i4;i+)=0;i4;i+) printf(“

温馨提示

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

评论

0/150

提交评论