[IT认证]指针详细介绍.ppt
《[IT认证]指针详细介绍.ppt》由会员分享,可在线阅读,更多相关《[IT认证]指针详细介绍.ppt(132页珍藏版)》请在三一办公上搜索。
1、void main(void)float s10=90,95,88,70,65,86,74,80,92,84;float aver=ave(s,10);cout“aver=“avern;,float ave(float a,int n)int i;float sum=a0;for(i=1;in;i+)sum=sum+ai;return sum/10;,float ave(float*a,int n)int i;float sum=a0;for(i=1;in;i+)sum=sum+ai;return sum/10;,第7章 指针,本章导读,指针是C+语言编程中最重要的概念之一,也是最容易产生困惑
2、并导致程序出错的问题之一。,指针用于存储数据和程序的地址,这是指针的基本功能。,利用指针编程可以表示各种数据结构,进行各种奇妙有效的运算;,通过指针可使主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯;并能像汇编语言一样处理内存地址,从而编写出精练而高效的程序。,本章提要:,1变量地址的概念,2一级及多级指针的概念,3指针的定义与引用,4一维数组与指针的关系,5二维数组与指针的关系,6字符串和指针的关系,7特殊指针常指针,8指针作为函数的参数,9引用,10动态数据的申请和释放,字节地址的概念,系统根据程序中定义变量的类型,给变量分配一定的长度空间。字符型占1个字节,整型数占4个字
3、节.。内存区的每个字节都有编号,称之为地址。,内存单元的地址,内存单元的内容,7.2 指针,变量地址概念,设有说明语句:char ch=65;int i=8;float x=3.14;,变量的两种访问方式,1、直接访问,按变量名字存取变量的值。cini;实际上是按地址将输入直接放到定义 i 单元中。,2、间接访问,将变量的地址存放在另一个单元p中,通过 p 取出变量的地址,再针对变量操作。,指针的概念,一个变量的地址称为该变量的指针。,如果在程序中定义了一个变量或数组,那么,这个变量或数组的地址(指针)也就确定为一个常量。,变量的指针和指向变量的指针变量,变量的指针就是变量的地址,当变量定义后
4、,其指针(地址)是一常量。,int i;,&i:2000H,可以定义一个变量专门用来存放另一变量的地址,这种变量称之为指针变量。在编译时同样分配一定字节的存储单元,未赋初值时,该存储单元内的值是随机的。,7.2.1 指针变量的定义,指针变量定义的一般形式为:,类型标识符*变量名,int*i_point;,指针类型,变量名,指针变量同样也可以赋值:,int i;int*i_point=,2000H,i,2000H,运算符*和指针变量,一个指针变量只能指向同一类型的变量。即整型指针变量只能放整型数据的地址,而不能放其它类型数据的地址。&运算符表示“地址”。,*在定义语句中只表示变量的类型是指针,没
5、有任何其它意义。int*p=&a,*和指针变量结合表示“指向”,表示对指针变量指向的内存单元(变量)进行读/写操作。*p=3,*point=5;,表示指向,表示类型,5,int i;,int*point=,指针和指向,指针变量只能指向和其同类型的变量,不能指向其它类型的变量,也不能指向常量和表达式。C+允许将一个常量经强制类型转换后赋值给指针变量。int*p=(int*)0 x2000;/初始化指针变量p,使其值为0 x2000float*f=(float*)100;/初始化指针变量f,使其值为100,如果在定义指针变量时没有初始化,其值是随机的、不确定的(静态存储类型、文件作用域类型的除外,
6、=0)。例:定义指针变量,使其指向另一个变量。int i,*p;/指针p的值是随机的p=/指针赋值,使其指向变量i,p指向不确定,不能用,例:通过指针变量,输入/输出数据。#includevoid main(void)int a,b,*p1,*p2;p1=/通过指针输出,间接表示a,间接表示b,7.2.2 指针变量的引用,a,b,&a,&b,p1,p2,4,8,输出:4 8 4 8,直接输出变量,通过指针引用间接输出变量,例:指针必须指向某变量后才能正确引用。void main(void)int x,y,*p1,*p2;*p1=5;*p2=10;,错误,p1和p2未指向任何变量,void ma
7、in(void)int x,y,*p1,*p2;p1=,正确,例:通过指针交换变量。输入a,b两个整数,按大小输出这两个数。void main(void)int*p1,*p2,*p,a,b;cinab;/输入a、b p1=,b,p1,p2,a,&a,&b,4,8,b,p1,a,&a,&b,4,p2,8,交换前,交换后,对于指针变量,系统也为其分配地址,同样可以定义一个变量来存放其地址。int x,*p1,*p2;p1=二级指针变量的定义和赋初值方法如下:*=初值;,p2,p1,x,&p1,&x,可以缺省,7.2.3 多级指针,在+语言中,把这种指针型变量称为“指针的指针”,意为这种变量是指向指
8、针变量的指针变量,也称多级指针。通常使用的多级指针是二级指针,相对来说,前面介绍的指针变量可以称为“一级指针”。,int*ptr=,但是:pptr=,则:*ptr相当于i*ptr=5相当于i=5*pptr也相当于i*pptr=8相当于i=8*pptr相当于ptr*pptr=&i相当于ptr=&i,非法,基类型不符,设有:,7.3.1 指针与一维数组 一级指针与一维数组的关系十分密切。指向一维数组的指针变量,实际上是指向一维数组元素的指针变量。可以利用指向一维数组的指针变量,完成对数组数据的操作处理。,int a5,*p,*p1;p=a;p1=&a0,p指向a,p1指向a0,int a10,*p
9、;p=/正确,p指向a5,数组名为一常指针,不能赋值和修改,说明一个指针变量(注意类型要与数组元素相同)并使之指向数组的某个元素,则可以使用该指针变量来操作数组。int a10,b10;int*ptra,*ptrb;ptra=由于指针使用的灵活性,可以在一个数组定义后再用指针对数组进行处理。例:用指针访问数组.cpp,总结(对一维数组):1)数组名等同于数组第0个元素的地址,也就是数组的起始地址,相当于一个常指针。2)指针指向数组的首地址后,其值+i后指向数组的第i个元素。3)指针指向数组a的首地址后,可以用指针代替数组名使用,*(point+i)、*(a+i)、ai、pointi、*ai、*
10、pointi等同,都是表示一维数组的第i个元素。若point指向a2,*(point+i)表示什么?,指针变量的运算主要有三种:赋值运算、算术运算和关系运算。,1.赋值运算inta,*pa;pa=相同类型指针赋值,把变量a的地址赋予指针变量pb,7.3.2 指针的运算,同类型指针赋值的含义是什么?,char*ptr;ptr=Iloveyou!;把字符串的首地址赋予指针变量char*str;cin.getline(str);/错误指针变量str未赋值,指向不确定,可以对指针变量赋0值。指针变量赋0值后称为空指针,空指针不指向任何地方。int*p=0;/p不指向任何地方 或 int*p=NULL;
11、/p不指向任何地方,NULL相当于0指针#define NULL 0,2.指针的算术运算inta5,*pa;pa=a;/pa指向数组a,也就是指向a0 pa=pa+2;/pa指向a2,即pa的值为&pa2一般的,在指针指向一个数组后,指针加减一个整数的算术运算才有实际意义。指针变量加减一个整数n的含义是将指针指向的位置向前或向后移动n个元素。指针偏移,一般的,当有了定义“int a10,*p=a;”后,有:*(p+1)=2;/p+1为a1地址*(a+1)=2;/a+1为a1地址*+p=2;/+p为a1地址p=p+1;*p=2;/p=p+1与+p等价a1=2;/直接对数组元素赋值p1=2;/指针
12、名作数组名用这些行是等价的,都是使a1为2。,int c=7,b=5,a=3,*p=/设&a=2000H,则有(*运算符是左结合的):(*p)+;/相当于a+。表达式为3,a=4,p不变*p+;/*p+首先*p,然后p=p+1,指针指向b,/表达式为3,p2004H,a不变+*p/相当于+(*p),就是*p=*p+1,即a=4*+p/相当于*(+p),首先:p=p+1,然后取*p。/即p先指向b,再取b的内容。表达式为5,/p2004H,(*p)+、+*p,*p+、*+p,4,a,注意进行算术运算的是指针本身还是指针指向的对象,两个指针变量之间只能做减法算术运算。只有指向同一数组的两个指针变量
13、之间的减法才有意义。两指针相减所得之差是两个指针所指数组元素之间相差的元素个数。指针变量之间的加法和乘除法没有意义 设有:int a10,*p1,*p2;p1=则:p2-p1的值为3,就是p2、p1所指数组元素下标的差。,指向同一数组的两指针变量进行关系运算可表示它们所指数组元素之间的关系。设:int a10,*p1=则:p2p1 值为真,因为p2的值大于 p1的值。即&a5&a0 p2=p1 值为假,因为p1和p2不是 指向同一个变量(值不同)p1!=0 值为真,因为p1指向了 a0,不是空指针。,3.指针的关系运算,例:使用指针处理数组 void main(void)int a10,i;i
14、nt*p;for(i=0;iai;for(p=a;p=a+9;p+)cout*pt;,p=a使p指向数组a;a+9为一常指针,指向数组a的最后一个元素,p=a+9表示指针p指向移动时,不能超出数组最后一个元素。,for(p=a;p=a+9;)cout*pt;,p+,p,每次p+,p就指向a的下一个元素,4.指针参与混合运算及优先级(补充)(1)*和/指针定义&*p1:先*运算再&运算&a 即a的地址(p1的值)*&p1:先&运算再*运算*(p1的指针)即变量p1值*&a:相当于*p1,即a*&放到一起互相抵消,(2)*和/指针定义 p1=&a0,b=*p1+/先取a0的值,赋值后,再使指针加1
15、,b=100/此后p1不指向a0,指向a1 p1=&a0,b=*+p1/先+p1再*p1,左结合,b=200,p1指向a1,p1=&a0,b=(*p1)+/相当于a0+,此后p1仍指向a0/b=100先赋值,a0=101,+优先级低 p1=&a0,b=*(p1+)/相当于*p1+,括号不起作用,比较特殊/b=100,p1指向a1 p1=&a0,b=+*p1/相当于+(*p1),左结合/b=101,a0=101,p1指向a0 在涉及到与指针变量相关的操作时,特别要注意操作对象是指针变量本身还是指针变量所指的对象,以及指针变量变化后实际所指的对象。,例:输入n(不大于20)个整型数存入一维数组,用
16、指针变量处理数组元素的方式将其逆序存放后输出。n从键盘输入。分析:用指针处理数组逆序,需要定义两个指针,具体的思路为:首先设置两个指针变量,分别指向数组的首地址(第0个元素,首指针)和数组的尾地址(最后一个元素,尾指针)。然后用循环处理,每次交换首、尾指针指向的两个元素,再令首指针后移一个元素;尾指针前移一个元素,为下一次交换做好准备。,开始时,pb指向a0,pe指向a9。在交换*pb和*pe后,pb+指向后一个元素,pe-指向前一个元素,再进行交换,反复进行,直到pb=pe。过程如下图所示:,pb,pe,交换*pb、*pe,10,1,2,3,4,5,6,7,8,9,7.3.3 指针与二维数组
17、,二维数组是“数组的数组”,即二维数组是由若干个一维数组所组成的。二维数组有三种地址:数组地址、行地址和元素地址。设有定义“int a34;”,则三种地址为:数组首地址:a 行地址:a+0、a+1、a+2 元素地址:a i 或a i+j或&a i j 等,int a34;/设数组a的首地址是2000H,a,数组首地址是2000H,三个行地址分别是2000H、2010H和2020H,各数组元素地址从2000H到202CH连续分布。a0、a1、a2为组成二维数组a的3个一维数组名字(一维数组名是元素指针)。,下面分析二维数组名与其所分解成的多个一维数组名之间的关系。a=一维数组名是一个元素指针二维
18、数组名是一个行指针,ai:表示第i行第0列元素的地址a+i:表示第i行地址(偏移i行)&ai:表示第i行地址,&不表示取地址,用来区 分元素地址和行地址.*(a+i):表示第i行第0列元素的地址,*不表示 取内容,用来区分元素地址和行地址.元素指针ai前加&转换成行指针行指针(a+i)前加*转换成元素指针 元素指针算术运算是偏移多少元素行指针算术运算是偏移多少行结合指针偏移的概念理解元素指针和行指针是不同的指针*的4种作用:乘、指针定义、取内容、区分为元素地址(运算符&),a00=*a0=*(*a);ai0=*ai=*(*(a+i);aij=*(ai+j)=*(*(a+i)+j);&aij=a
19、i+j=*(a+i)+j;,二维数组地址和元素的表示法,使用二维数组名、指向运算符和取地址运算符,二维数组元素有着多种表示方法,例如(优先级()*):*(a+1)+2=&a12*(*(a+1)+2)=a12*(a+1)=*(a1)=*(&a10)=a10(*(a+1)1=(a1)1=b1=a11/b=a1*(a+1)1=*(a+1)1)=*(b1)=*(&b10)=b10=a20/b=a+1,行指针,例:指针访问二维数组.CPP,7.3.4 指针数组 由同类型指针所组成的数组称为指针数组。或者当某个数组被定义为指针类型,就称这样的数组为指针数组。指针数组的每个元素都是一个指针变量。定义指针数组
20、的一般格式为:*;可以给指针数组赋初值,赋初值有多种方式,同普通的数组。定义指针变量时的数据类型可以选取任何基本数据类型,也可以是结构体类型、枚举类型或类类型。,设有:“int a,b,c,*p3=”,,数组名,指针个数,初始化地址,定义一整型数组和指针数组,通过指针数组来输出整型数组。void main(void)int a=10,20,30,40,50,60;int*p=,输出结果:10 20 30 40 50 60,void main(void)a5=1,3,5,7,9,*pa5,*p=pa,i;for(i=0;i5;i+)pai=,p=p+1;指向pa数组下一个元素,13579,p=&
21、pai,例:指针数组.cpp,7.3.5 指向二维数组的指针二维数组名不能赋值给一级指针和二级指针 对于一个m列的二维数组anm,可以定义一个指向它的指针:“int(*p)m;”。就可以赋值:“p=a;”。这里的指针p称为“指向数组的指针”。定义指向数组的指针的一般形式为:(*)指向二维数组的指针可以用来代替二维数组名,使用指向二维数组的指针输出二维数组中的元素。void main()int a34=0,1,2,3,4,5,6,7,8,9,10,11;int(*p)4,i,j;p=a;/指针p指向二维数组a(起始地址)for(i=0;i3;i+)/使用相对于a数组起始地址的偏移量 for(j=
22、0;j4;j+)/用指针+偏移量生成临时指针 cout*(*(p+i)+j)t;/使用行指针p+偏移量 cout*(pi+j)t;/使用列指针pi+偏移量 cout*(*(a+i)+j)t;/使用行指针a+偏移量 cout*(ai+j)n;/使用列指针ai+偏移量,7.4 指针与函数,在C+中,指针与函数的关系密切复杂。与数组名一样,函数名也是一个常指针。函数的参数可以是指针,函数的返回值也可以是指针。还可以定义指向函数的指针。指针作函数参数,形参要求是指针变量,实参要求分为以下几种情况。实参为数组名 实参为地址 实参为指针,一、实参用数组名,形参用指针变量,void main(void)in
23、t a 10;.f(a,10);.,f(int*x,int n).,实参数组,形参指针,7.4.1 指针作为函数参数,#define N 10/选择排序void sele_sort(int*p)/形参为指针,指向实参数组int i,j,k,temp;for(i=0;iN-1;i+)k=i;/设左端点元素值最小,记下其下标i for(j=i+1;jN;j+)/与最小元素ak比较if(pjpk)k=j;/记下较小元素下标j if(k!=i)/最小元素和左端点元素交换 temp=pi;pi=pk;pk=temp;,指针名作数组名用数组方式排序,void main()int aN,i;coutai;s
24、ele_sort(a);/数组名作实参调用排序函数cout排序后的数据为:n;for(i=0;iN;i+)/输出排序后的数组coutait;coutn;,void sele_sort(int*p)/形参为指针,指向实参数组int temp,*p1,*p2,*p3;for(p1=p;p1p+N-1;p1+)p3=p1;/p3指向左端点,假设这个元素最小 for(p2=p1+1;p2p+N;p2+)/p2指向的元素与最小元素比较if(*p2*p3)p3=p2;/当前元素比最小值小,记下其地址if(p3!=p1)/如果最小值不是左端点元素,就将其和左端点元素交换temp=*p1;*p1=*p3;*p
25、3=temp;,完全指针方式排序,二、实参为地址,形参用指针变量,void main(void)int a,b;p=a;.f(.,f(int*x,int*y).,实参地址,形参指针,接收的是地址的值,例:将两个整数按从小到大的顺序输出。voidexchang(int*p1,int*p2)/指针作形参intp;p=*p1;*p1=*p2;*p2=p;/p1、p2所指向的实参变量交换数据void main()inta,b;cinab;if(ab)exchang(,实参为地址,输入数据:9 4 运行结果:4 9,if(ab)exchang(/主调,传地址voidexchang(int*p1,int*
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- IT认证 IT 认证 指针 详细 介绍
链接地址:https://www.31ppt.com/p-4593943.html