第 指针引用和链表.pptx
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《第 指针引用和链表.pptx》由会员分享,可在线阅读,更多相关《第 指针引用和链表.pptx(152页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、 内存中的一个字节为一个存储单元(内存中的一个字节为一个存储单元(Byte)。)。存储单元的编号称为存储单元的编号称为地址地址。变量的地址变量的地址是指该变量所在存储区域的第一个是指该变量所在存储区域的第一个 字节(单元)的地址。字节(单元)的地址。9.1 指针和指针变量指针和指针变量 9.1.1 指针的概念指针的概念例:例:int a;float b;char c;10401044c(char)b(float)1048a(int)这三个地址就称为变量这三个地址就称为变量a、b、c的指针。的指针。第1页/共152页指针也是一个数值,C+提供了一种类型的变量用于存放地址值,即存放指针,这种变量就
2、是指针变量。9.1.2指针变量的定义指针变量的定义格式:类型说明符*指针变量名;例:例:int *pi;定义定义 pi 为为指向指向 int 类类型变量型变量的指针变量的指针变量 float *pf;定义定义 pf 为为指向指向 float 类型变量类型变量的指针变量的指针变量int*为为int型指针类型标识符型指针类型标识符。float*为为float型指针类型标识符。型指针类型标识符。第2页/共152页几点说明:几点说明:一个指针变量只能指向同一数据类型的变量,该一个指针变量只能指向同一数据类型的变量,该 数据类型是在定义指针变量时明确给定的。数据类型是在定义指针变量时明确给定的。C+语言
3、规定有效数据的指针不指向语言规定有效数据的指针不指向0单元单元(为非为非0值值),如果指针变量值为如果指针变量值为0,即,即NULL(在在ios.h中已定义中已定义),表示空指针,即表示空指针,即不指向任何变量不指向任何变量。不要把地址值与整数类型值相混淆。不要把地址值与整数类型值相混淆。例如:地址例如:地址2000与整型量与整型量2000是两个不同的概念。是两个不同的概念。第3页/共152页1、&取地址运算取地址运算 功能:功能:返回变量的内存地址返回变量的内存地址 例例9.1 int*p,m;/定义定义 p 为指向为指向 int 类型变量的指针类型变量的指针 m=200;p=&m;/将整型
4、变量将整型变量 m 的地址值赋给指针变量的地址值赋给指针变量 p9.1.3有关指针的运算符&和*其意义见下一页其意义见下一页!第4页/共152页10401040m(int)2000p(int*)200假定变量假定变量m 的地址是的地址是1040第5页/共152页2002、*间接存取运算间接存取运算 功能:功能:访问指针指向的变量访问指针指向的变量例例9.2 int*p,m=200,n;p=&m;p 指向整型变量指向整型变量 m。n=*p;将将p指向的值指向的值(即即m的值的值)赋给赋给 n。*p=100;将将 100 赋给指针变量赋给指针变量 p 所指向的变量所指向的变量 mpm&m100执行
5、语句执行语句*p=100;n200执行语句执行语句n=*p;通过通过p间接访问间接访问m第6页/共152页9.1.4 指针变量的初始化指针变量的初始化 初始化格式:初始化格式:类型说明符类型说明符*指针变量名指针变量名=初始地址值初始地址值;例:例:char c,*p1;p1=&c;/*赋值语句,定义后进行赋值语句,定义后进行*/例:例:char c;char *pc=&c;/*指针初始化,定义时进行指针初始化,定义时进行*/两种方式等效第7页/共152页9.1.5 直接访问和间接访问直接访问和间接访问在C+中定义的所有变量,编译器都会记录它们的属性,便于以后对它们的访问,如在例9.1中定义的
6、两个变量m和p,编译器记录的属性如下表:表9-1变量及其属性变量名变量名变量类型变量类型 变量地址变量地址 m int1040pint*2000第8页/共152页1.直接存取方式(直接访问)按变量地址存取变量值的方式称为直接存取方式,在程序中体现为直接使用变量名来存取变量值2.间接存取方式(间接访问)如果变量如果变量 p 存放着变量存放着变量 m 的地址,那么的地址,那么,对变量对变量 m 的访问可以首先访问变量的访问可以首先访问变量 p,取得,取得变量变量 m 的地址,然后按该地址进行对的地址,然后按该地址进行对 m 的存取的存取操作操作,称为间接存取方式。称为间接存取方式。在程序中体现为通
7、过在程序中体现为通过 p 来存取变量来存取变量 m 的值。的值。例:例:m=5,n=m 直接存取直接存取 m*p=5,n=*p 间接存取间接存取 mp1040m104020005间接存取的前提是什么?第9页/共152页总结:总结:&m-获得变量获得变量 m 的地址。的地址。*p-为指针变量为指针变量 p 所指向的内容。所指向的内容。记住:记住:已知已知 int *p,m;p=&m;则则 p&m 等价等价 *p m第10页/共152页例例9.3 变量的直接访问和间接访问变量的直接访问和间接访问#include void main()char c=A;char*cp=&c;cout c *cp e
8、ndl;c=B;cout c *cp endl;*cp=a;cout c *cp endl;输出:?输出:?AA BB aa第11页/共152页例例9.4 变量的直接访问和间接访问变量的直接访问和间接访问 int a=1;float b=5.2;char c=A;int *p1;float*p2;char *p3;p1=&a;p2=&b;p3=&c;cout a ,b ,c endl;cout *p1 ,*p2 ,*p3 endl;运行结果:?运行结果:?1,5.2,A1,5.2,A续:续:*p1=*p1+1;*p2=*p2+2;*p3=*p3+3;cout a ,b ,c endl;运行结果
9、:?运行结果:?2,7.2,D第12页/共152页关于指针使用的几点说明:关于指针使用的几点说明:指针变量必须通过初始化或赋值获得值后(即必须指针变量必须通过初始化或赋值获得值后(即必须明确指向某一变量),才可以利用它进行间接访问。明确指向某一变量),才可以利用它进行间接访问。若有若有 int m;int*p=&m ;划线部分的意义是将划线部分的意义是将m的地址赋给的地址赋给p,而不是将而不是将m的地址赋给的地址赋给p指向的空间。指向的空间。上述两个语句的意义等价于上述两个语句的意义等价于:int m;int*p;p=&m;注意指针变量的指向类型,只有相同类型数据变量注意指针变量的指向类型,只
10、有相同类型数据变量的地址才能赋给该指针变量。即整型变量的地址只能的地址才能赋给该指针变量。即整型变量的地址只能赋给整型指针。如在例赋给整型指针。如在例9.4中,若出现中,若出现 p1=&b;是无是无意义的。意义的。第13页/共152页关于指针使用的几点说明(续):关于指针使用的几点说明(续):同类型指针变量之间可以相互赋值,不同类型的指针同类型指针变量之间可以相互赋值,不同类型的指针变量一般不能相互赋值,如在例变量一般不能相互赋值,如在例9.4中,若出现中,若出现 p1=p2;是无意义的。是无意义的。允许将一个整型常数经强制类型转换后赋给指针变量,允许将一个整型常数经强制类型转换后赋给指针变量
11、,如:如:float*fpp;fpp=(float*)5000;其意义:将其意义:将5000作为一个地址值赋给指针变量作为一个地址值赋给指针变量fpp。第14页/共152页例例9.5 交换两个指针的指向交换两个指针的指向p1x10p2y20p1x10p2y20t目标目标int x=10,y=20;int *p1=&x,*p2=&y,*t;建立初始状态建立初始状态cout*p1 t*p2 endl;t=p1;p1=p2;p2=t;cout*p1 t*p2 endl;输出结果输出结果?10 2020 10t第15页/共152页例例9.6 通过指针通过指针,交换两个指针所指向的变量的值交换两个指针所
12、指向的变量的值p1x10p2y20t目标目标int x=10,y=20,t;int *p1=&x,*p2=&y;建立初始状态建立初始状态输出结果输出结果?10 2020 10p1x20p2y10t10cout x,y endl;t=*p1;*p1=*p2;*p2=t;cout x,y endl;第16页/共152页9.1.6 地址值的输出地址值的输出 例例9.7#include void main(void)int a,*p1;float b,*p2;double d,*p3;p1=&a;p2=&b;p3=&d;cout p1=p1 endl;cout p2=p2 endl;cout p3=p
13、3 第17页/共152页 地址值的输出地址值的输出(输出十进制地址值输出十进制地址值)例:例:#include void main()int a,*p1;float b,*p2;double d,*p3;p1=&a;p2=&b;p3=&d;cout p1=(int)p1 endl;cout p2=(int)p2 endl;cout p3=int(p3)endl;输出结果:输出结果:p1=6684148 p2=6684140 p3=6684132亦可亦可第18页/共152页 指针使用的常见错误指针使用的常见错误 1、使用未初始化的指针变量使用未初始化的指针变量 void main()int x,
14、*p;x=0;*p=x;.2、指针变量所指向的数据类型与其定义的类型不符指针变量所指向的数据类型与其定义的类型不符 void main()float x,y;int*p;p=&x;y=*p;.第19页/共152页#include/复习voidmain()intx=10,y;int*p1=&x,*p2;/指针的定义及初始化p2=&y;/指针的赋值*p2=*p1+5;/通过指针间接存取变量cout*p2endl;第20页/共152页撤消撤消例例9.8 基本类型量作函数参数基本类型量作函数参数#include void swap(int x,int y)int t;t=x;x=y;y=t;void
15、main()int x=3,y=9;swap(x,y);cout x,yendl;输出?输出?3x9y实参实参3x9y形参形参传值调用传值调用t933t局局部部动动态态变变量量3,9main()工作区工作区swap1()工作区工作区9.2 指针作函数参数指针作函数参数9.2.1基本类型量作函数参数基本类型量作函数参数 实参x、y和形参x、y是不同的变量,占据不同的存储空间。参数传递时:intx=x,inty=y;第21页/共152页3x9y撤消撤消例例9.9指针作函数参数指针作函数参数#include void swap(int*px,int*py)int t;t=*px;*px=*py;*p
16、y=t;void main()int x=3,y=9,*p1,*p2;p1=&x;p2=&y;swap(p1,p2);cout x,y1)/*n 是是最大最大公约数公约数*/*num=*num/n;*den=*den/n;/*直接对主调函数中的实参直接对主调函数中的实参进行间接访问操作进行间接访问操作*/第23页/共152页例:约简分数(例:约简分数(续续)#include void main(void)int a=14,b=21;cout “分数:分数:”;cout a /b endl;cout “约减后:约减后:”;lowterm(&a,&b);cout a /b endl;输出:输出:分
17、数分数:14/21 约减后:约减后:2/3第24页/共152页假定:假定:b=1000,且两个数组连续存放且两个数组连续存放则:则:a=?9.3 指针和指向数组的指针指针和指向数组的指针9.3.1 一维数组与指针一维数组与指针 1.数组名数组名-数组元素在内存中连续存放,数组元素在内存中连续存放,数组名数组名是该存储区的起始地址,是该存储区的起始地址,是是地址常量。地址常量。例:例:int a10;float b10;a 是是 a0 元素的起始地址。元素的起始地址。b 是是 b0 元素的起始地址。元素的起始地址。1040b0b1b2.内存内存.baa0a1a2第25页/共152页2.指向一维数
18、组元素的指针变量指向一维数组元素的指针变量例:例:int a10;/假定假定a的值为的值为1040 int*p;/p是指向整型变量的指针是指向整型变量的指针,a数组的元素为整型变量,数组的元素为整型变量,那么那么 p 可以指向可以指向 a 数组的任意元素。数组的任意元素。p=a;/结果结果 p=1040,p 指向指向a0p+;/结果结果 p=1044p+;/结果结果 p=1048p-;/结果结果 p2=1044向下移动一个元素的位置向下移动一个元素的位置若若 p=&a6;则则*p 访问访问a6第26页/共152页3.指针可进行的运算(一般为加、减、比较运算)指针可进行的运算(一般为加、减、比较
19、运算)(1)指针指针数值数值 (2)指针指针-指针指针 (3)指针指针 比较比较 指针指针(1)指针指针数值数值 运算的意义运算的意义如果:如果:p 是指针,是指针,n 是数值是数值 则:则:pn 表示表示 p 向后向后/向前移动向前移动 n 个元素位置。个元素位置。即:结果即:结果 p 的值的值n*c若若 p 是是 int 型指针,则型指针,则 c 等于等于 4若若 p 是是 char 型指针,则型指针,则 c 等于等于 1若若 p 是是 float 型指针,则型指针,则 c 等于等于 4 .第27页/共152页例9.11用指针间接访问数组元素#includevoidmain(void)in
20、ta10=1,2,3,4,5,6,7,8,9,10,*p=a;intsum=0,i;for(i=0;i10;i+)sum=sum+*(p+i);/*(p+i)piaifor(i=0;i10;i+,p+)/指针变量可进行自加、自减运算cout*p;coutsum=sumendl;第28页/共152页 指向相同数据类型的指针变量可以相减,其结果指向相同数据类型的指针变量可以相减,其结果 为两指针所指向地址之间数据的个数。为两指针所指向地址之间数据的个数。例:例:int*px,*py,n,a5;px=&a1;py=&a4;n=py-px;3个数组元素个数组元素pxpya1a4(2)指针指针-指针指针
21、 运算的意义运算的意义结果:结果:n 值为值为3第29页/共152页=!=(3)指针指针 比较比较 指针指针指针的关系运算是两个指针所指向的地址之间的指针的关系运算是两个指针所指向的地址之间的比较运算,产生的结果为比较运算,产生的结果为 0(假)(假)和和 1(真)(真)。第30页/共152页例:有定义:例:有定义:double a5,*p1,*p2;p1,p2 的的指向如图所示。指向如图所示。p1=NULL 判断判断p1是否为空指针?是否为空指针?(NULL是系统定义的是系统定义的)结果结果:0aa0a1a2a3a4p1p2计算:计算:p1=p2 判断判断p1,p2是否指向同一变量?是否指向
22、同一变量?结果结果:0 p1p2 判断判断p1的地址是否比的地址是否比p2的地址小?的地址小?结果:结果:1 p1!=0 判断判断 p1 是否是否不为不为空指针?空指针?结果:结果:1第31页/共152页例9.12改写例9.11,注意指针的比较运算。#includevoidmain(void)inta10=1,2,3,4,5,6,7,8,9,10,*p;intsum=0;for(p=a;pa+10;p+)sum=sum+*p;for(p=a;pa+10;p+)/需重新给p赋初值cout*p;coutsum=sumendl;第32页/共152页以上定义等价于:以上定义等价于:int a10,*p
23、;p=a;a,a0a1.a9p例:inta10,*p;p=&a0;int a10;int*p=&a0;int a10;int*p=a;a&a04.如何获取数组任一元素的地址、任一数组元素的值如何获取数组任一元素的地址、任一数组元素的值 a是int*类型的指针。第33页/共152页第第i个元素地址的表示个元素地址的表示(p的初值为的初值为a):a+i 数组名法数组名法 p+i 指针法指针法&ai 下标法下标法&pi 下标法下标法第第i个元素值的表示个元素值的表示(p的初值为的初值为a):*(a+i)数组名法数组名法 *(p+i)指针法指针法 ai 下标法下标法 pi 下标法下标法a9a0a1.a
24、,p.aii个元素个元素通过指针变量和数组名访问元素的通过指针变量和数组名访问元素的重要区别重要区别:1.指针变量是地址变量,指针变量是地址变量,其其指向由所赋值确定。指向由所赋值确定。2.数组名是地址常量(指针常量)数组名是地址常量(指针常量),恒定指向,恒定指向 数组的第数组的第1个元素。个元素。p=a;p+;正确a=p+2;a+;错误a+i第34页/共152页例9.12P179数组元素逆向存放#includevoidmain(void)inta10=1,2,3,4,5,6,7,8,9,10,t;int*p1=a,*p2=a+9;while(p1p2)t=*p1;*p1=*p2;*p2=t
25、;p1+;p2-;for(p1=a;p1a+10;p1+)cout*p1t;coutendl;第35页/共152页void reverse(int b,int n)int i,j,t;i=0;j=n-1;while(ij)t=bi;bi=bj;bj=t;i+;j-;void main(void)int a10=1,2,3,4,5,6,7,8,9,10,i;reverse(a,10);for(i=0;i10;i+)cout ai t ;cout endl;图例9.14将数组元素逆向存放。9.3.2一维数组元素指针作函数参数一维数组元素指针作函数参数 在被调函数中数组元素的值被改变后,自动带回主函
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 指针引用和链表 指针 引用
![提示](https://www.deliwenku.com/images/bang_tan.gif)
限制150内