c语言课件第10章指针1011.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《c语言课件第10章指针1011.ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 课件 10 指针 1011
- 资源描述:
-
1、第十章第十章 指指 针针掌握指针与指针变量的概念;掌握指针与指针变量的概念;掌握数组的指针和指针数组的使用;掌握数组的指针和指针数组的使用;掌握字符串指针和指向字符串的指针变掌握字符串指针和指向字符串的指针变量的使用;量的使用;掌握指针函数和函数指针的使用;掌握指针函数和函数指针的使用;了解指向指针的指针的概念及其使用。了解指向指针的指针的概念及其使用。预预 备备 知知 识识内存:内存:CPU处理的数据都保存在内存中。内存分为一个个单元,这些单元顺序排列,每一个单元有一个称为内存地址的编号,对内存数据的访问都是通过地址进行的。高级语言用变量等高级概念把内存单元、地址等低级概念掩盖起来,使我们在
2、写程序时不必关心硬件的细节,但内存与地址仍是最基本的概念。存储单元的最小单位是字节。1.内存的概念内存的概念地址:地址:为了对内存中的某个存储单元进行访问,要为它编号,这种编号称为内存地址。通过地址我们就能够访问该地址所标识的存 储单元。2.地址的概念地址的概念变量的地址:变量的地址:每一个变量在内存中总占用几个连续的每一个变量在内存中总占用几个连续的 字节,开始字节的地址,就是变量的地址。字节,开始字节的地址,就是变量的地址。20072007存储单元10.1 10.1 指针及其相关概念指针及其相关概念 指针:指针:一个变量的地址称为该变量的指针。许多高级语一个变量的地址称为该变量的指针。许多
3、高级语言都把程序对象的地址作为一种数据,称之为地址值或言都把程序对象的地址作为一种数据,称之为地址值或指针值。指针值。指针变量:指针变量:若一个变量专用于存放另一个变量的地址若一个变量专用于存放另一个变量的地址(指针),则该变量称为指针变量。换句话说,以地址(指针),则该变量称为指针变量。换句话说,以地址为值的变量称为指针变量,简称指针。为值的变量称为指针变量,简称指针。指针的对象:指针的对象:当把变量的地址存入指针变量后,当把变量的地址存入指针变量后,我们就可以说我们就可以说这个指针指向了该变量这个指针指向了该变量。变量的存取方法:变量的存取方法:直接存取和间接存取。直接存取和间接存取。直接
4、存取:直接存取:直接根据变量名存取数据。直接根据变量名存取数据。间接存取:间接存取:通过指针变量存取相应变量的数据通过指针变量存取相应变量的数据。10.2.2 变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量一、指针变量的定义一、指针变量的定义 一般形式:一般形式:类型标识符类型标识符 *变量名变量名 ;例如:int*ptr1,*ptr2;指针变量的类型:指针变量的类型:说明该指针所指向的变量的类型。说明该指针所指向的变量的类型。在定义指针变量时要注意以下几个问题在定义指针变量时要注意以下几个问题:变量名变量名ptr2前面的前面的“*”不能省略,如果写成不能省略,如果写成 int*
5、ptr1,ptr2;则则ptr2被定义为整型变量,而非整型指针变量。被定义为整型变量,而非整型指针变量。定义中的定义中的“*”表示所定义的变量是指针变量,但表示所定义的变量是指针变量,但 指针变量名是指针变量名是ptr1、ptr2,而非而非*ptr1、*ptr2。指针变量只能指向定义时所规定类型的变量。指针变量只能指向定义时所规定类型的变量。这个规定的类型称为该指针变量的这个规定的类型称为该指针变量的“基类型基类型”。如:上例中ptr1、ptr2只能指向整型变量,不 能指向实型或字符型变量。其“基类型”相同,都是整型。定义指针变量后,并未确定该变量指向何处。定义指针变量后,并未确定该变量指向何
6、处。也就是说该变量的值是不确定的。在引用指针也就是说该变量的值是不确定的。在引用指针 变量前必须首先让它指向一个变量,这一点非变量前必须首先让它指向一个变量,这一点非 常重要。常重要。二、指针变量的运算二、指针变量的运算 指针运算符指针运算符(“&”和和“*”)“&”(取地址运算符取地址运算符):取变量的存储地址:取变量的存储地址“*”(取值运算符取值运算符):取指针所指向变量的内容:取指针所指向变量的内容 例如:&a 是求变量a的地址。ptr指向了i变量,*ptr表示i的值,即3 我们还可以用这种方法实现对变量的改变:我们还可以用这种方法实现对变量的改变:*ptr=15;等价于等价于 i=1
7、5;由此可见由此可见:通过指针运算符“*”可以引用一个变量。如:当ptr已经指向变量i后,*ptr就等同于i。*ptr&i进一步理解进一步理解“&”和和“*”:“&”运算和运算和“*”运算是一对互逆运运算是一对互逆运算。算。&*ptr&i ptr *&i *ptr i等价于 指针的赋值运算(指针的赋值运算(=)指针的赋值运算指针的赋值运算:就是把地址赋值给指针变量。:就是把地址赋值给指针变量。指针的赋值运算可以是以下三种方式指针的赋值运算可以是以下三种方式:使用取地址运算符,把地址值赋值给指针变量。使用取地址运算符,把地址值赋值给指针变量。如:int i,*pi;pi=&i;把指针变量的值赋给
8、另一个指针变量。把指针变量的值赋给另一个指针变量。如:int i,*pa,*pb;pa=&i;pb=pa;给指针变量赋值为符号常量给指针变量赋值为符号常量NULL。说明说明:NULL是一个空指针,表示该指针变量的值没是一个空指针,表示该指针变量的值没有意义。作用是为了避免对没有被初始化的指针变有意义。作用是为了避免对没有被初始化的指针变量的非法引用。量的非法引用。NULL 的定义在的定义在“stdio.h”中。中。如:int*pi;pi=NULL;说明:说明:在定义指针变量时,可以立即将一个地址值在定义指针变量时,可以立即将一个地址值 赋给指针变量,这就是指针变量的初始化。赋给指针变量,这就是
9、指针变量的初始化。指针变量的初始化也是指针的赋值运算。指针变量的初始化也是指针的赋值运算。如:如:float flt,*f_ptr=&flt;注意:这不是给注意:这不是给*f_ptr赋值赋值。指针变量间的赋值和引用应保证基类型相同。指针变量间的赋值和引用应保证基类型相同。若有定义:若有定义:int*p,i;float*q,x;则:则:q=&i;p=&x;移动指针的运算移动指针的运算 指针的加减运算(指针的加减运算(+、)、)指针的自加自减运算(指针的自加自减运算(+,-,+=,-=)1 1指针的指针的+、运算、运算 指针整数指针指针+、说明说明:指针与整型值加减的结果是指针指针与整型值加减的结
10、果是指针,表示使该指针,表示使该指针指向该指针下移或上移存储单元个数指向该指针下移或上移存储单元个数(整型值整型值)之后之后的内存地址。存储单元的大小就是该指针的数据类的内存地址。存储单元的大小就是该指针的数据类型所需的内存大小。型所需的内存大小。例如:ptr+n(指针ptr,n为整数)这个指针值代表的内存单元的地址是:ptr+n*d(其中d是指针所指向变量的数据类型所占内存字节数),即指针移动了n个元素。指针与指针的加运算毫无意义,所以指针与指针的加运算毫无意义,所以指针与指针指针与指针 没有加运算没有加运算。指针与指针的减运算要求相减的两个指针属于同指针与指针的减运算要求相减的两个指针属于
11、同 一类型,其结果是整数,表示两个指针之间的数一类型,其结果是整数,表示两个指针之间的数 据的个数。其结果值的计算公式是:据的个数。其结果值的计算公式是:ptr1-ptr2=(ptr1的值-ptr2的值)/指针的数据类型所占的字节数 例如:int*ptr1,*ptr2,*ptr3,x;int ary5=2,4,8,16,32;ptr1=&ary0;ptr2=&ary3;ptr3=ary;x=ptr2-ptr1;x 的值是32 2指针的指针的+、-、+=+=、-=-=运算运算 +、+=+=:是移动指针到下一个或下几个存储单元。是移动指针到下一个或下几个存储单元。-、-=-=:是移动指针到上一个或
12、上几个存储单元。是移动指针到上一个或上几个存储单元。例如:例如:int*ptr,ary5=2,4,6,8,10;ptr=ary;ptr+=3;ptr-;想一想:想一想:*ptr+和和(*ptr)+有什么区别有什么区别?关系运算关系运算 基类型相同的两个指针进行比较运算,其意义是两个指针的位置比较,结果是逻辑值。指针运算的程序举例:指针运算的程序举例:把把a,b按大小顺序输出。按大小顺序输出。main()int*p1,*p2,*p,a,b;a=45;b=76;p1=&a;p2=&b;if(*p1*p2)p=p1;p1=p2;p2=p;printf(a=%d,b=%d,max=%d,min=%d,
13、a,b,*p1,*p2);输出结果:a=45,b=76,max=76,min=45三、指针变量作为函数参数三、指针变量作为函数参数 指针可以用作函数参数,这在调用函数希望指针可以用作函数参数,这在调用函数希望改变参数的值时非常有用。改变参数的值时非常有用。例如:用指针变量编写实现两个数的交换的函数例如:用指针变量编写实现两个数的交换的函数void swap(int*p1,int*p2);main()int x1=100,x2=200;printf(x1=%d,x2=%dn,x1,x2);swap(&x1,&x2);printf(x1=%d,x2=%dn,x1,x2);void swap(int
14、*p1,int*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;图示交换过程中存储单元内容的变化:图示交换过程中存储单元内容的变化:123456想一想:想一想:如果函数的参数不用指针而用整型变如果函数的参数不用指针而用整型变量量,能否实现值的交换?为什么?,能否实现值的交换?为什么?通过函数调用得到通过函数调用得到n个要改变的值的方法:个要改变的值的方法:在主调函数中设在主调函数中设n个变量,用个变量,用n个指针变量指向它们;个指针变量指向它们;将指针变量作实参,将这将指针变量作实参,将这n个变量的地址传给所调用个变量的地址传给所调用 的函数的形参;的函数的形参;通
15、过形参指针变量,改变该通过形参指针变量,改变该n个变量的值;个变量的值;主调函数中就可以使用这些改变了值的变量。主调函数中就可以使用这些改变了值的变量。注意:注意:不能企图通过改变指针形参的值而使指不能企图通过改变指针形参的值而使指 针实参的值改变。针实参的值改变。如:上例如:上例swap函数中不能写成:函数中不能写成:temp=p1;p1=p2;p2=temp;10.3 10.3 数组的指针和指向数组的指针变量数组的指针和指向数组的指针变量 一、概念一、概念 数组的指针数组的指针:是数组的起始地址。:是数组的起始地址。数组元素的指针数组元素的指针:是数组元素的地址。:是数组元素的地址。当指针
16、变量指向数组或数组元素时,它当指针变量指向数组或数组元素时,它就是就是指向数组的指针变量指向数组的指针变量。C规定规定:数组名代表数组的首地址(起始地址),数组名代表数组的首地址(起始地址),也就是数组第一个元素的地址。也就是数组第一个元素的地址。当指针变量当指针变量p指向数组的某个元素时,指向数组的某个元素时,p+1指向数组的下一个元素。假设一个整指向数组的下一个元素。假设一个整型元素占两个字节,型元素占两个字节,p+1是使是使p的地址加的地址加2个字节。个字节。如:如:int a10,*p;则:则:p=a;与与 p=&a0;等价等价称指针变量称指针变量p指向数组元素指向数组元素a0 p+i
17、、a+i、&ai 都是都是ai的地址。的地址。二、数组元素的引用二、数组元素的引用 1.用下标法引用数组元素用下标法引用数组元素如:如:a3=45;b25=200;2.用指针法引用数组元素用指针法引用数组元素 假如:假如:int a10,*p,i;p=a;则:则:*(p+i)、*(a+i)则代表元素则代表元素ai *(p+i)也可以写成也可以写成pi *(p+i)、*(a+i)、ai、pi 等价,等价,都代表数组都代表数组a的第的第i+1个元素。个元素。程序举例:输出程序举例:输出10个元素数组中的全部元素。个元素数组中的全部元素。方法二:通过数组名计算数组元素地址,找出元素的方法二:通过数组
18、名计算数组元素地址,找出元素的 值。值。main()int a10=54,65,8,2,3,56,8,21,57,98,i;for(printf(n),i=0;i10;i+)printf(%4d,*(a+i);方法一:下标法。方法一:下标法。main()int a10=54,65,8,2,3,56,8,21,57,98,i;for(printf(n),i=0;i10;i+)printf(%4d,ai);方法三:用指针变量指向数组元素方法三:用指针变量指向数组元素 main()int a10=54,65,8,2,3,56,8,21,57,98,*p,i;p=a;for(printf(n),i=0
19、;i10;i+)printf(%4d,*p+);以上三种方法,利用指针变量效率最高。以上三种方法,利用指针变量效率最高。说明:指针变量与数组名的区别:说明:指针变量与数组名的区别:指针变量是地址变量,指针变量是地址变量,数组名是地址常量数组名是地址常量。即。即指针变量的内容可以在程序运行过程中被改变;而指针变量的内容可以在程序运行过程中被改变;而数组名一旦被定义,它的地址就不能再改变了。数组名一旦被定义,它的地址就不能再改变了。例如:int i,*p,a6;则:p=&i;a=&i;a+;a+=i;不能给常量赋值利用指针变量编程时特别要注意指针变量利用指针变量编程时特别要注意指针变量 的当前值。
20、的当前值。例如:通过指针变量输入输出a数组元素。main()int*p,i,a10;p=a;for(i=0;i10;i+)scanf(%d,p+);printf(“n”);for(i=0;i10;i+)printf(“%6d”,*p+);应插入语句 p=a;注意:注意:*p+、*(p+)、(*p)+、*(+p)的含义的含义 三、数组名作函数的参数三、数组名作函数的参数 例如:f(int arr,int n)main()int array10;f(array,10);现在解释:实际上,能够接受并存放地址值的只能是指针变量。因此,C编译系统都是将形参数组名作为指针变量来处理的。上例中f(int a
21、rr,int n)等价于等价于 f(int*arr,int n)。arri=*(arr+i)使用形参数组的概念只是为了与实参数组对应,直观,便于理解而已。例:从例:从10个数中找出其中最大值和最小值(用数组)。个数中找出其中最大值和最小值(用数组)。main()void max_min(int a,int n,int*max,int*min);int i,a=2,4,1,6,7,32,45,75,45,90,max,min;printf(The original array=);for(i=0;i10;i+)printf(%5d,ai);max_min(a,10,&max,&min);prin
22、tf(max=%d,min=%d,max,min);void max_min(int a,int n,int*max,int*min)int i;*max=*min=a0;for(i=1;in;i+)if(*maxai)*min=ai;上例中如果形参数组用指针变量,则程序如下:上例中如果形参数组用指针变量,则程序如下:main()void max _min(int*x,int n,int*max,int*min);int i,a10=2,4,1,6,7,32,45,75,45,90,max,min;for(printf(The original array=),i=0;i10;i+)print
23、f(%5d,ai);max_min(a,10,&max,&min);printf(“max=%d,min=%d,max,min);void max_min(int*x,int n,int*max,int*min)int i;*max=*min=*x;for(i=1;in;i+)if(*max*x)*min=*(x+i);数组名做函数参数小结数组名做函数参数小结:如果有一个实参数组,想在函数中改变此数组如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参都可用数组名或指针变量。的元素的值,实参与形参都可用数组名或指针变量。其对应关系有以下其对应关系有以下4种情况:种情况:实参与形参都用
24、数组名;实参与形参都用数组名;实参用数组名,形参用指针变量;实参用数组名,形参用指针变量;实参、形参都用指针变量;实参、形参都用指针变量;实参为指针变量,形参用数组名。实参为指针变量,形参用数组名。注意:注意:用指针变量作实参时一定要有确定的值。用指针变量作实参时一定要有确定的值。例例a:实参和形参都用数组名:实参和形参都用数组名main()int a10;f(a,10);f(int x,int n)例例b:实参用数组名,形参用指针变量:实参用数组名,形参用指针变量main()int a10;f(a,10);f(int*x,int n)例例c:实参、形参都用指针变量:实参、形参都用指针变量ma
25、in()int a10,*p;p=a;f(p,10);f(int*x,int n)例例d:实参为指针变量,形参用数组名:实参为指针变量,形参用数组名main()int a10,*p;p=a;f(p,10);f(int x,int n)本章程序举例:本章程序举例:习题习题10.1:输入:输入3个整数,按由小到大的顺序输出。个整数,按由小到大的顺序输出。void swap(int*p,int*q);main()int a,b,c,*p1=&a,*p2=&b,*p3=&c;scanf(“%d%d%d”,p1,p2,p3);if(*p1*p2)swap(p1,p2);if(*p1*p3)swap(p1
展开阅读全文