C语言课件教学PPT-第10章-指针-.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《C语言课件教学PPT-第10章-指针-.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 课件 教学 PPT 10 指针
- 资源描述:
-
1、第十章 主要内容主要内容 10.1地址和指针的概念地址和指针的概念 10.变量的指针和指向变量的变量的指针和指向变量的 指针变量指针变量 10.数组与指针数组与指针 10.字符串与指针字符串与指针 10.指向函数的指针指向函数的指针 10.返回指针值的函数返回指针值的函数 10.指针数组和指向指针的指针指针数组和指向指针的指针 10.8有关指针的数据类型和指针运算的小结有关指针的数据类型和指针运算的小结 10.1地址和指针的概念(1)计算机硬件系统的内存储器中,拥有大)计算机硬件系统的内存储器中,拥有大量的量的存储单元(容量为字节存储单元(容量为字节)。)。为了方便管理,必须为每一个存储单元编
2、号,为了方便管理,必须为每一个存储单元编号,这个编号就是存储单元的这个编号就是存储单元的“地址地址”。每个存储单。每个存储单元都有一个惟一的地址。元都有一个惟一的地址。1.内存地址内存地址内存中内存中存储单元的编号存储单元的编号(2)在地址所标识的存储单元中存放数据。)在地址所标识的存储单元中存放数据。注意:内存单元的注意:内存单元的地址地址与内存单元中的与内存单元中的数据数据是两个完全不同的概念。是两个完全不同的概念。2.变量地址变量地址系统分配给系统分配给变量的内存单元的变量的内存单元的起始地址起始地址假设有这样一个程序:假设有这样一个程序:main()int num;scanf(%d,&
3、num);printf(num=%dn,num);C编译程序编译到该变量定义语句时,编译程序编译到该变量定义语句时,将变量将变量num 登录到登录到“符号表符号表”中。符号表的关键属性有两个:一是中。符号表的关键属性有两个:一是“标识符名标识符名(id)”,二是该标识符在内存空间中的,二是该标识符在内存空间中的“地址(地址(addr)”。为描述方便,假设系统分配给变量为描述方便,假设系统分配给变量num的的2字节存储单元为字节存储单元为 2000 和和2001,则起始地址,则起始地址2000就是变量就是变量num在内存中的地址。在内存中的地址。3.变量值的存取变量值的存取通过变量在内存中的地址
4、进行通过变量在内存中的地址进行系统执行系统执行“scanf(”%d“,&num);”和和“printf(”num=%dn“,num);”时,存取变量时,存取变量num值的方式可以有两种:值的方式可以有两种:(1)直接访问直接访问直接利用变量的地址进行存取直接利用变量的地址进行存取 1)上例中上例中scanf(“%d”,&num)的执行过程是这的执行过程是这样的:样的:用变量名用变量名num作为索引值,检索符号表,作为索引值,检索符号表,找找到变量到变量num的起始地址的起始地址2000;然后将键盘输入的;然后将键盘输入的值(假设为)送到内存单元值(假设为)送到内存单元2000和和2001中。此
5、中。此时,变量时,变量num在内存中的地址和值在内存中的地址和值 2)printf(num=%dn,num)的执行过程,的执行过程,与与scanf()很相似:很相似:首先找到变量首先找到变量num的起始地址的起始地址2000,然后从,然后从2000和和2001中取出其值,最后将它输出。中取出其值,最后将它输出。(2)间接访问间接访问通过通过另一变量访问该变量的值另一变量访问该变量的值 语言规定:在程序中可以定义一种特殊的变量(称语言规定:在程序中可以定义一种特殊的变量(称为为指针变量指针变量),用来存放其它变量的),用来存放其它变量的地址地址。例如,假设定义了这样一个指针变量例如,假设定义了这
6、样一个指针变量num_pointer,它被分配到它被分配到4000、4001单元,其值可通过赋值语句单元,其值可通过赋值语句“num_pointer=num;”得到。此时,指针变得到。此时,指针变量量num_pointer的值就是变量的值就是变量num在内存中的起始在内存中的起始地址地址2000.通过指针变量通过指针变量num_pointer存取变量存取变量num值的过程如值的过程如下:下:首先找到指针变量首先找到指针变量num_pointer的地址(的地址(4000),取),取出其值出其值2000(正好是变量(正好是变量num 的起始地址);的起始地址);然然后从后从2000、2001中取出
7、变量中取出变量num的值(的值(3)。)。在语言中,指针是在语言中,指针是一种特殊的变量一种特殊的变量,它是,它是存放地址存放地址的。的。(3)两种访问方式的比较)两种访问方式的比较 两种访问方式之间的关系,可以用某人甲(系两种访问方式之间的关系,可以用某人甲(系统)要找某人乙(变量)来类比。统)要找某人乙(变量)来类比。一种情况是,甲知道乙在何处,直接去找就是一种情况是,甲知道乙在何处,直接去找就是(即直接访问)。(即直接访问)。另一种情况是,甲不知道乙在哪,但丙(指针另一种情况是,甲不知道乙在哪,但丙(指针变量)知道,此时甲可以这么做:先找丙,变量)知道,此时甲可以这么做:先找丙,从丙处获
8、得乙的去向,然后再找乙(即间接从丙处获得乙的去向,然后再找乙(即间接访问)。访问)。指针和指针变量的定义:指针和指针变量的定义:一个变量的地址称为该变量的“指针指针”。例如,地址2000是变量的指针。如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量指针变量”。上述的i_pointer就是一个指针变量。为表示指针变量和它指向的变量之间的关系,用指针运算符为表示指针变量和它指向的变量之间的关系,用指针运算符“*”表示。表示。例如,指针变量例如,指针变量num_pointer与它所指向的变量与它所指向的变量num的关系,的关系,表示为:表示为:*num_pointer,即,即*
9、num_pointer等价于变量等价于变量num。因此,下面两个语句的因此,下面两个语句的作用相同作用相同:num=3;/*将将3直接赋给变量直接赋给变量num*/num_pointer=#/*使使num_pointer指向指向num*/*num_pointer=3;/*将将3赋给指针变量赋给指针变量num_pointer所所指向的变量指向的变量*/10.2 变量的指针和指向变量的指 针变量10.10.1.1 定义一个指针变量定义一个指针变量定义指针变量的一般形式为基类型基类型 *指针变量名;指针变量名;下面都是合法的定义:float *pointer_;char*pointer_;可
10、以用赋值语句使一个指针变量得到另一个变量的地址,从而使它指向一个该变量。例如:例如:pointer_;pointer_;在定义指针变量时要注意两点:在定义指针变量时要注意两点:(1)指针变量前面的指针变量前面的“*”,表示该变量的类型为指针型,表示该变量的类型为指针型变量。变量。例例:float *pointer_1;指针变量名是指针变量名是pointer_1,而不是,而不是*pointer_1。(2)在定义指针变量时必须指定在定义指针变量时必须指定基基类型。类型。需要特别注意的是,只有整型变量的地址才能放到指向需要特别注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中。下面的赋值是
11、错误的整型变量的指针变量中。下面的赋值是错误的 float a;int *pointer_1;pointer_1=&a;10.2.2 10.2.2 指针变量的引用指针变量的引用 注意注意:指针变量中只能存放地址(指针),不要将一个整数(或任何其他非地址类型的数据)赋给一个指针变量。例例10.通过指针变量访问整型变量通过指针变量访问整型变量#include voidmain()int,;int*pointer_,*pointer_;pointer_;/*把变量的地址赋给 pointer_1*/pointer_;/*把变量的地址赋给 pointer_*/printf(%,%,);printf(%,
12、%,*pointer_,*pointer_);对对“”和和“*”运算符说明:运算符说明:如果已执行了语句 pointer_;(1)*pointer_的含义是什么?的含义是什么?“”和“*”两个运算符的优先级别相同,但按自右而左方向结合。因此,*pointer_与相同,即变量a的地址。如果有pointer_2*pointer_;它的作用是将(的地址)赋给pointer_2,如果pointer_2原来指向,经过重新赋值后它已不再指向了,而指向了。(2)*的含义是什么?的含义是什么?先进行运算,得的地址,再进行*运算。*和*pointer_的作用是一样的,它们都等价于变量。即*与等价。(3)(*po
13、inter_)相当于。)相当于。例例10.2 输入和两个整数,按先大后小的顺序输出输入和两个整数,按先大后小的顺序输出 和。和。#include void main()int*1,*2,*,;scanf(,);1;if();printf(=,=,);printf(max=,min=,*1,*2);运行情况如下:运行情况如下:,当输入,时,由于,当输入,时,由于,将和交换。交换前的情况见图将和交换。交换前的情况见图(),交换后见图()。(),交换后见图()。注意:注意:此例中此例中a和和b并未交并未交换,而换,而p1和和p2的值改变。的值改变。10.10.3.3 指针变量作为函数参数指针变量作为
14、函数参数例例10.3 对输入的两个整数按大小顺序输出对输入的两个整数按大小顺序输出#include void main()void swap(int*,int*);int,;int*pointer_,*pointer_;scanf(,);pointer_;pointer_2;if()swap(pointer_,pointer_2);printf(,);void swap(int*,int*)int temp;temp*1;*;*temp;注意:注意:此例中此例中a和和b已经交换,而已经交换,而pointer_,pointer_2的值未改变。的值未改变。被调用函数不能被调用函数不能改变实参指针变
15、量的值,但可以改变它们改变实参指针变量的值,但可以改变它们所指向的变量的值。所指向的变量的值。为了利用被调用函数改变的变量值,为了利用被调用函数改变的变量值,应该使应该使用指针(或指针变量)作函数实参用指针(或指针变量)作函数实参。其机。其机制为:在执行被调用函数时,使制为:在执行被调用函数时,使形参指针形参指针变量所指向的变量的值发生变化;函数调变量所指向的变量的值发生变化;函数调用结束后,通过用结束后,通过不变的实参指针不变的实参指针(或实参(或实参指针变量)将变化的值保留下来。指针变量)将变化的值保留下来。例例10.输入、输入、3个整数,按大小顺序输出。个整数,按大小顺序输出。#incl
16、ude void main()void exchange(int*1,int*2,int*3);int ,*,*,*;scanf(%,%,%,&,&,&);exchange(,);printf(,);void exchange(int*,int*,int*)void swap(int*,int*);if(*)swap(,);if(*)swap(,);if(*swap(,);void swap(int*,int*)int temp;temp*;*;*temp;10.3 数组与指针 一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变
17、量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元数组元素的指针就是数组元素的地址素的地址。10.3.1 10.3.1 指向数组元素的指针指向数组元素的指针数组的指针数组的指针数组在内存中的数组在内存中的起始地址起始地址,数组元数组元素素的指针的指针数组元素在内存中的起始地址。数组元素在内存中的起始地址。2.指向数组的指针变量的定义指向数组的指针变量的定义指向数组的指针变量的定义,与指向普通变量的指向数组的指针变量的定义,与指向普通变量的指针变量的定义方法一样。指针变量的定义方法一样。例如:例如:;(定义为包含个整型数据的数组定义为包含个整型数据的数
18、组)*;(定义为指向整型变量的指针变量定义为指向整型变量的指针变量)应当注意,如果数组为型,则指针变量的基类型亦应当注意,如果数组为型,则指针变量的基类型亦应为型。应为型。对该指针变量赋值:对该指针变量赋值:;把元素的地址赋给指针变量。也就是使指向数组的第号元素,如图:在在C中中,数组名代表数组的首地址。因此数组名代表数组的首地址。因此p=a;与与p=&a0;是等价的。是等价的。p=a;是将是将a 数组的首地址赋给指针变量数组的首地址赋给指针变量p。但这里的。但这里的a 并不代表整个数组。并不代表整个数组。上面定义可写成上面定义可写成:int*p=a;作用是把作用是把a数组首元素地址赋给指针变
19、量数组首元素地址赋给指针变量p(不是(不是*p)10.10.通过指针引用数组元素通过指针引用数组元素 若若p=a;是将整型数组是将整型数组a的首地址赋给整型指针变量的首地址赋给整型指针变量 p,则,则*p=5;是将整数是将整数5赋给赋给a数组的第一个元素数组的第一个元素a0,等价于,等价于a0=5。p+1表示指针变量表示指针变量p当前所指的数组元素的当前所指的数组元素的下一个元素下一个元素。但。但p+1 不是不是p的值加的值加 1。若有。若有 p=&a0;则则 p+i(或或a+i)就是就是 a i 的地址的地址 (因为因为a代表数组代表数组a的首地址的首地址)。若有若有p=&a0;则则*(p+
20、i)或或*(a+i)就是就是p+i或或a+i所指向的数组元素,所指向的数组元素,即即ai。也就是说。也就是说*(p+i)=*(a+i)=ai。指向数组的指针变量可以带下标,如:指向数组的指针变量可以带下标,如:pi 与与*(p+i)是等价的。是等价的。引用一个数组元素,可以用:()()下标法,如形式;下标法,如形式;()()指针法,如指针法,如*()或()或*()()。其中是数组名,是指向数组元素的指针变量,其初值。例例10.5 输出数组中的全部元素。输出数组中的全部元素。假设有一个数组,整型,有个元素。要输出各元素的值有三种方法:(1)下标法。#include void main()int;
21、int;for(;)scanf(,);printf();for(;)printf(,);(2)通过数组名计算数组元素地址,找出元素的值。#include voidmain()int;int;for(;)scanf(,);printf();for(;)printf(,*();(3)用指针变量指向数组元素。#include void main()int;int *,;for(;)scanf(,);printf();for(;();)printf(,*);这三种方法比较这三种方法比较:1.前两种效率相同,每次都要计算前两种效率相同,每次都要计算元素地址元素地址,费时较多。费时较多。2.第三种方法用指
22、针变量第三种方法用指针变量直指元素直指元素,不必每,不必每次从新计算地址,像次从新计算地址,像P+这样的运算速度很这样的运算速度很快,所以能大量提高执行效率。快,所以能大量提高执行效率。3.下标法下标法比较直观比较直观,能直接知道是第几个元,能直接知道是第几个元素,地址法或指针法不直观,需要仔细分析素,地址法或指针法不直观,需要仔细分析地址和指针的指向。地址和指针的指向。几个注意的问题:指针变量可以实现本身的值的改变。如p+是合法的;而a+是错误的。因为a是数组名,它是数组的首地址,是常量。要注意指针变量的当前值。请看下面的程序:例例10.通过指针变量输出数组的个元素。通过指针变量输出数组的个
23、元素。#include void main()int*,;for(;)scanf(,);printf();for(;,)printf(,*);程序运行情况:程序运行情况:1 2 3 4 5 6 7 8 9 0 22153 234 0 0 30036 25202 11631 8259 8237 28483显然输出的数值并不是数组中各元素的值显然输出的数值并不是数组中各元素的值#include void main()int*,;for(;)scanf(,);printg();p=a;for(;,)printf(,*);从上例可以看出,虽然定义数组时指定它包含从上例可以看出,虽然定义数组时指定它包含
24、10个元素,但指针变量可以指到数组以后的内存单个元素,但指针变量可以指到数组以后的内存单元,系统并不认为非法。元,系统并不认为非法。*p+,由于,由于+和和*同优先级,结合方向自同优先级,结合方向自右而左,右而左,等价于等价于*(p+)。*(p+)与与*(+p)作用不同。若作用不同。若p的初值为的初值为a,则,则*(p+)等价等价a0,*(+p)等价等价a1。(*p)+表示表示p所指向的元素值加所指向的元素值加1。如果如果p当前指向当前指向a数组中的第数组中的第i个元素,则个元素,则*(p-)相当于相当于ai-;*(+p)相当于相当于a+i;*(-p)相当于相当于a-i。10.10.3 .3
25、用数组名作函数参数用数组名作函数参数在第在第8章章8.7节中介绍过可以用数组名作函数的参数节中介绍过可以用数组名作函数的参数如:void main()i(int arr,int);int array;(array,);void(int arr,int)array为实参数组名,arr为形参数组名。在学习指针变量之后就更容易理解这个问题了。数组名就是数组的首地址,实参向形参传送数组名实际上就是传送数组的地址,形参得到该地址后也指向同一数组。这就好象同一件物品有两个彼此不同的名称一样。同样,指针变量的值也 是地址,数组指针变量 的值即为数组的首地址 ,当然也可作为函数的 参数使用。例例10 将数组中
展开阅读全文