新编C语言程序设计教程第8章1课件.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《新编C语言程序设计教程第8章1课件.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 新编 语言程序设计 教程 课件
- 资源描述:
-
1、第8章 指针第八章 指针 本章要求本章要求理解指针的概念;掌握指针变量的定义和使用方法;掌握指针变量作函数参数时,数据的传递方式;掌握使用指针处理一维、二维数组的方法;掌握使用指针处理字符串的方法。本章重点本章重点指针变量的定义和使用指针变量作函数参数使用指针处理一维数组和字符串 本章难点本章难点使用指针处理一维、二维数组第8章 指针1.1.内存与变量地址内存与变量地址v 内存地址:内存地址:内存是计算机用于存储数据的存储器,以一个字节作为存储单元,为了便于访问,给每个字节单元一个唯一的编号,第一字节单元编号为0,以后各单元按顺序连续编号,这些单元编号称为内存单元的地址。变量地址:变量地址:变
2、量所分配存储空间的首字节单元地址(字节单元编号)。第8章 指针 3 6 7 8 15 16 A公司公司B公司公司C公司公司一排平房一排平房 叫地址叫地址 第8章 指针第8章 指针2.变量的三要素:变量的三要素:名字、类型与值名字、类型与值 每个变量都通过每个变量都通过变量名与相应的存储单元相连系变量名与相应的存储单元相连系,具体,具体分配哪些单元给变量,由编译系统完成变量名到对应内分配哪些单元给变量,由编译系统完成变量名到对应内存单元地址的变换。存单元地址的变换。变量分配存储空间的变量分配存储空间的大小大小由由类型类型决定。决定。变量的值变量的值则是指相应则是指相应存储单元的内容存储单元的内容
3、。3.3.内存存取方式内存存取方式 直接存取直接存取:把直接按变量名或地址存取变量值的方式称:把直接按变量名或地址存取变量值的方式称为为“直接存取直接存取”方式。方式。间接存取间接存取:通过定义一种特殊的变量专门存放内存或变:通过定义一种特殊的变量专门存放内存或变量的地址,然后根据该地址值再去访问相应的存储单元量的地址,然后根据该地址值再去访问相应的存储单元。第8章 指针将要访问变量将要访问变量a a的地址存放在另一个变量的地址存放在另一个变量p p中,当需要中,当需要访问变量访问变量a a时,先取出变量时,先取出变量p p的内容即变量的内容即变量a a的地址,的地址,再根据此地址找到变量再根
4、据此地址找到变量a a所对应的存储空间。所对应的存储空间。这种间接的通过变量这种间接的通过变量p得到变量得到变量a的地址,再存取变量的地址,再存取变量a的的值的方式即为值的方式即为“间接存取间接存取”。能够存放其它变量地址的变量能够存放其它变量地址的变量称作指针变量称作指针变量 通常称变量通常称变量p p指向变量指向变量a a,变量,变量a a是变量是变量p p所指向的对象所指向的对象400012345400040024800pap(4800)p(4800)a(4000)4000123454000间接存取示意图间接存取示意图第8章 指针4、指针的概念、指针的概念 在语言中,用在语言中,用指针指
5、针来表示一个变量指向另一个来表示一个变量指向另一个变量这样的指向关系。变量这样的指向关系。指针和指针变量指针和指针变量 指针:是一个变量的指针:是一个变量的地址地址 指针变量:用来存储变量地址指针变量:用来存储变量地址(指针指针)的的变量变量如如:p即是一个指针变量即是一个指针变量,它存放的是它存放的是a的地址的地址4000。第8章 指针8.1.2 指针变量的定义与初始化指针变量的定义与初始化1.1.指针变量的定义指针变量的定义 类型标识符类型标识符 *指针变量名;指针变量名;例:float *p1;(定义p1为指向实型变量的指针变量)char *p2;(定义p2为指向字符型变量的指针变量)在
6、指针变量定义中,*是一个说明符,它表明其后的变量是指针变量,如p是指针变量,而不要认为“*p”是指针变量。指针变量定义时指定的数据类型不是指针变量本身(变量存放的值)的数据类型,而是指针变量所指向的对象(或称目标)的数据类型 指针变量存放的是所指向的某个变量的地址值,而普通变量保存的是该变量本身的值 指针变量并不固定指向一个变量,可指向同类型的不同变量第8章 指针2.2.指针运算符与地址运算符指针运算符与地址运算符 与指针引用有关的两个运算符:&与*。&:取地址运算符 *:指针运算符,或称指向运算符、间接访问运算 符。指针指向的对象的表示形式:*指针变量指针变量此处*是访问指针所指对象的运算符
7、,与指针定义时的*不同。第8章 指针3.3.指针变量初始化指针变量初始化若有定义:int a,*p;语句仅仅定义了指针变量p,但指针变量并未指向确定的变量(或内存单元)。因为这些指针变量还没有赋给确定的地址值,只有将某一具体变量的地址赋给指针变量之后,指针变量才指向确定的变量(内存单元)。指针变量初始化指针变量初始化:在定义指针时同时给指针一个初始值如:int a,*p=&a;40003a(4000)p*p第8章 指针4.指针变量的引用指针变量的引用 *指针变量名指针变量名代表所指变量的值。代表所指变量的值。指针变量名指针变量名代表所指变量的地址。代表所指变量的地址。有定义:int a,*p=
8、&a;用*p来表示p指向的对象a,*p与a是等价的。*p可以象普通变量一样使用。例如:a=12;*p=12;scanf(%d,&*p);scanf(%d,p);printf(“%d%d”,*p,a);注意注意:*与&具有相同的优先级,结合方向从右到左。这样,&*p即&(*p),是对变量*p取地址,它与&a等价;p与&(*p)等价,a与*(&a)等价。第8章 指针8.1.3 指针运算1.1.指针的赋值运算指针的赋值运算(1)将变量地址值赋给指针变量,使指针指向该变量。设有如下定义:int a,b,*pa,*pb;float*pf;第一行定义了整型变量a,b及指针变量pa,pb。pa、pb还没有被
9、赋值,因此pa、pb没有指向任何变量,下面语句完成对pa,pb的赋值:pa=&a;pb=&b;第8章 指针例如:int j,k;int*pointer1,*pointer2;pointer1=&j;pointer2=&k;pointer1jpointer2k第8章 指针(2)相同类型的指针变量间的赋值相同类型的指针变量间的赋值 pa与pb都是整型指针变量,它们间可以相互赋值,如:pb=pa;即 pa,pb都指向变量a,此时a、*pa、*pb是等价的。指针指向变化如下图:注意注意:只有相同类型的指针变量才能相互赋值,如pf=pa;是不允许的。因为pa是整型指针,pf是浮点型指针。&a&bpapb
10、a,*pab,*pb&a&apapba,*pa,*pbb第8章 指针()给指针变量赋()给指针变量赋空值空值 给指针变量赋空值,说明该指针不指向任何变量。“空”指针值用NULL表示,NULL是在头文件stdio.h中预定义的常量,其值为,在使用时应加上预定义行,如:#include stdio.h int *pa=NULL;亦可以用下面的语句给指针赋“空值”:pa=0;或:pa=0;这里指针pa并非指向0地址单元,而是具有一个确定的“空值”,表示pa不指向任何变量。注意注意:指针虽然可以赋值0,但却不能把其它的常量地址赋给指针。例如:pa=4000;是非法的。第8章 指针例 8.1 指针定义与
11、初始化main()int a,b;int*pointer_1,*pointer_2;a=100;b=10;pointer_1=&a;pointer_2=&b;printf(%d,%dn,a,b);printf(%d,%dn,*pointer_1,*pointer_2);第8章 指针程序运行结果:100,10100,10&a&bbpointer_1pointer_2a*pointer_1*pointer_2第8章 指针例8.2 从键盘上输入两个整数到a、b,按由大到小输出。#include main()int a,b,*pa=&a,*pb=&b,*p;/*定义指针变量pa、pb,如下页图a*/s
12、canf(%d%d,&a,&b);if(*pa*pb)p=pa;/*进行指针交换,如下页图b,c*/pa=pb;pb=p;printf(n a=%d,b=%dn,a,b);printf(n max=%d,min=%d,*pa,*pb);/*pa指向大数,pb指向小数*/第8章 指针若输入:12 22输出结果:a=12,b=22 max=22,min=12 (b)(c)指针变化示意图1222ppapb1222ppapbpapbab ab ab第8章 指针2.2.指针的算术运算指针的算术运算 (1)加减运算:一个指针可以加、减一个整数n,其结果与指针所指对象的数据类型有关。指针变量的值应增加或减少
13、“nsizeof(指针类型)”。加减运算常用于数组的处理加减运算常用于数组的处理。对指向一般数据的指针,加减运算无实际意义。例如:int a10,*p=a,*x;x=p+3;/*实际上是p加上3*2个字节赋给x,x指向数组的第三个分量*/对于不同基类型的指针,指针变量“加上”或“减去”一个整数n所移动的字节数是不同的。例如:float a10,*p=a,*x;p=p+3;/*实际上是p加上3*4个字节赋给x,x依然指向数组的第三个分量*/第8章 指针(2)自增自减运算指针变量自增、自减运算具有上述运算的特点,但有前置后置、先用后用的考虑,务请小心。例如:int a10,*p=a,*x;x=p+
14、;/*x第一个元素分量,p指向第二个元素*/x=+p;/*x、p均指向数组的第二个分量*/*p+相当于*(p+)。*(p+)与(*p)+含义不同,前者表示地址自增地址自增,后者表示当前当前所指向的数据自增所指向的数据自增。第8章 指针2.*&a的含意是什么?(答:a)3.(*p)+相当于什么?(答:a+)思考:1.若有定义 int a,*p;执行了“p=&a”,则:“&*p”的含意是什么?(答:相当于&a)第8章 指针3.3.指针的关系运算指针的关系运算 与基本类型变量一样,指针可以进行关系运算。与基本类型变量一样,指针可以进行关系运算。在关系表达式中允许对两个指针进行所有的关系运算。若在关系
15、表达式中允许对两个指针进行所有的关系运算。若p,q是两个同类型的指针变量,则:是两个同类型的指针变量,则:pq,p=q都都是允许的。是允许的。指针的关系运算在指向数组的指针中广泛的运用,假设指针的关系运算在指向数组的指针中广泛的运用,假设 p、q是指向同一数组的两个指针,执行是指向同一数组的两个指针,执行pq的运算,其含义为,的运算,其含义为,若表达式结果为真(非值),则说明若表达式结果为真(非值),则说明p所指元素在所指元素在q所指元素所指元素之后。或者说之后。或者说q所指元素离数组第一个元素更近些。所指元素离数组第一个元素更近些。注意:在指针进行关系运算之前,指针必须指向确定的变量注意:在
16、指针进行关系运算之前,指针必须指向确定的变量或存储区域,即指针有初始值;另外,只有相同类型的指针才或存储区域,即指针有初始值;另外,只有相同类型的指针才能进行比较。能进行比较。第8章 指针8.1.4 8.1.4 多级指针多级指针 把指向指针型数据的指针变量称为指向指针的指针,或。二级指针的定义形式如下:数据类型 *指针变量例如:int a,*p,*pp;a=22;p=&a;pp=&p;假设变量a的地址为4000,指针p的地址为4100,二级指针pp的地址为4800。a、p、pp三者的关系如上图。&p=4100&a=400022pp(4800)p(4100)a(4000)第8章 指针8.2 指针
17、与函数8.2.1 8.2.1 指针作为函数参数指针作为函数参数 利用指针作函数参数,可以实现函数之间多个数利用指针作函数参数,可以实现函数之间多个数据的传递,当形参为指针变量时,其对应实参可以是据的传递,当形参为指针变量时,其对应实参可以是指针变量或存储单元地址。指针变量或存储单元地址。(1)(1)函数形参为指针变量,用函数形参为指针变量,用指针变量指针变量作为实参作为实参 (2)(2)函数形参为指针变量,用函数形参为指针变量,用变量地址变量地址作为实参作为实参例例8.3 编写一个交换两个变量的函数,在主程序中编写一个交换两个变量的函数,在主程序中 调用,实现两个变量值的交换。调用,实现两个变
18、量值的交换。第8章 指针程序如下:#includemain()int a,b;int *pa,*pb;void swap(int*p1,int*p2);/*函数声明函数声明*/scanf(%d%d,&a,&b);pa=&a;/*pa指向变量指向变量a*/pb=&b;/*pb指向变量指向变量b */swap(pa,pb);printf(na=%d,b=%dn,a,b);或:swap(&a,&b);void swap(int*p1,int*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;程序运行结果如下:程序运行结果如下:输入:输入:12 22 输出:输出:a=22,b
19、=12第8章 指针两点说明:(1)若在函数体中交换指针变量的值,实参若在函数体中交换指针变量的值,实参a、b的值并不的值并不改变,指针参数亦是传值。改变,指针参数亦是传值。例如:例如:int *p;p=p1;p1=p2;p2=p;不要希望如此完成处理。不要希望如此完成处理。(2)函数中交换值时不能使用无初值的指针变量作临时变函数中交换值时不能使用无初值的指针变量作临时变量。量。例如:例如:int *p;*p=*p1;*p1=*p2;*p2=*p;p无确定值,对无确定值,对 p的使用可能带来不可预期的后果。的使用可能带来不可预期的后果。第8章 指针8.2.2 指针函数指针函数指针函数:是指返回值
20、为指针的函数是指返回值为指针的函数指针函数的定义形式:指针函数的定义形式:类型标示符类型标示符 *函数名(参数)函数名(参数)例如:例如:int int*fun(int a,int b)fun(int a,int b)函数体语句函数体语句 在函数体中有返回指针或地址的语句,形如在函数体中有返回指针或地址的语句,形如:return (&变量名变量名);或或 return (指针变量指针变量);并且返回值的类型要与函数类型一致。并且返回值的类型要与函数类型一致。第8章 指针例8.3 分析如下程序main()int a,b,*p;int *max(int x,int y);scanf(“%d,%d”
21、,&a,&b);p=max(a,b);printf(“max=%d”,*p);int *max(int x,int y)if(xy)return (&x);else return (&y);第8章 指针8.2.3 指向函数的指针 一个函数包括一组指令序列,存储在某一段内存中,这段内一个函数包括一组指令序列,存储在某一段内存中,这段内存空间的起始地址称为存空间的起始地址称为函数的入口地址函数的入口地址 称函数入口地址为称函数入口地址为函数的指针函数的指针。代表函数的入口地址代表函数的入口地址 可以定义一个指针变量,其值等于该函数的入口地址,指向这可以定义一个指针变量,其值等于该函数的入口地址,指
22、向这个函数,这样通过这个指针变量也能调用这个函数。这种指针变个函数,这样通过这个指针变量也能调用这个函数。这种指针变量称为量称为指向函数的指针变量指向函数的指针变量。定义指向函数的指针变量的一般形式为定义指向函数的指针变量的一般形式为:类型标识符(类型标识符(*指针变量名指针变量名)()();例如:例如:int (*p)();/*指针变量指针变量p可以指向一个整型函数可以指向一个整型函数*/float (*q)();/*指针变量指针变量q可以指向一个浮点型函数可以指向一个浮点型函数*/第8章 指针 刚定义的指向函数的指针变量,亦象其它指针变量一样要赋刚定义的指向函数的指针变量,亦象其它指针变量
23、一样要赋以地址值才能引用。当将某个函数的入口地址赋给指向函数的以地址值才能引用。当将某个函数的入口地址赋给指向函数的指针变量,就可用该指针变量来调用所指向的函数指针变量,就可用该指针变量来调用所指向的函数 给函数指针赋初值:将函数名(函数的入口地址值)赋给指给函数指针赋初值:将函数名(函数的入口地址值)赋给指针变量针变量 例如例如 int m,(*p)();int max(int a,int b);则可以则可以 p=max;/*p指向函数指向函数max()*/指针调用函数的指针调用函数的 一般形式为一般形式为:(*指针变量指针变量)()(实参表实参表);如上例:如上例:m=(*p)(12,22
24、);/*比较比较 m=max(12,22);*/第8章 指针注意:用函数指针调用函数是间接调用,没有参数类型说明,用函数指针调用函数是间接调用,没有参数类型说明,C编译系统也无法进行类型检查,因此,在使用这种形编译系统也无法进行类型检查,因此,在使用这种形式调用函数时要特别小心。实参一定要和指针所指函数式调用函数时要特别小心。实参一定要和指针所指函数的形参类型一致。的形参类型一致。函数指针可以作为函数参数,此时,当函数指针每次函数指针可以作为函数参数,此时,当函数指针每次指向不同的函数时,可执行不同的函数来完成不同的功指向不同的函数时,可执行不同的函数来完成不同的功能能 例例 8.48.4 函
25、数函数max()max()用来求一维数组的元素的最大值,在用来求一维数组的元素的最大值,在主调函数中用函数名调用该函数与用函数指针调用该函主调函数中用函数名调用该函数与用函数指针调用该函数来实现。数来实现。第8章 指针程序如下:#include stdio.h#define M 8 main()float sumf,sump;float aM=11,2,-3,4.5,5,69,7,80;float(*p)();/*定义指向函数的指针p*/float max(float a,int n);/*函数声明*/p=max;/*函数名(函数入口地址)赋给指针p*/sump=(*p)(a,M);/*用指针
展开阅读全文