《C++指针的运用.ppt》由会员分享,可在线阅读,更多相关《C++指针的运用.ppt(51页珍藏版)》请在三一办公上搜索。
1、第5章指针的应用,5.1、指针概述一、内存地址的概念地址编码的基本单位是字节,每个字节是一个基本内存单元。二、从内存单元中存取数据的 方法1、通过变量名,称为直接访问方式,直接对变量的存储单元进行存取访问。在变量获得内存空间的同时,变量名也就成为了相应内存空间的名称,在变量的整个生存期内都可以用这个名字访问该内存空间,表现在程序语句中就是通过变量名存取变量内容。,2、通过地址,称为间接访问方式,先找到存放变量的地址的变量,得到变量的地址,再根据变量的地址找到变量的存储单元,对它进行存取访问。C+拥有在运行时获得变量的地址和操纵地址的能力。变量的地址可以使用地址运算符&求得,在某一变量前加上地址
2、运算符&,则为该变量的地址,如:&x表示变量x的地址数组名表示数组的首地址;函数的地址用函数名表示。用来存放地址的变量就叫做指针型变量,简称指针。,假设ptr为一指针,则语句:ptr=/将x的值赋给y,例5.1、阅读如下程序:源程序清单:#includeusing namespace std;void main()int a;int*p;a=10;p=,5.2、指针变量的定义、赋值及使用一、指针变量的定义指针本身也是一种变量,须先声明后使用。声明指针类型的变量是在声明变量的同时加上*来完成的。对应于各种类型的数据都有相应的指针类型。*放在指针定义中时,被称为指针定义符。放在可执行语句中的指针前
3、被称为指针运算符,也称为“间接访问”运算符。,指针变量的声明语句,由数据类型后跟星号,再跟随指针变量名组成。数据类型*指针变量名;如:int*iptr;int*iptr;int*iptr;int*iptr;在指针定义中,一个*只能表示一个指针。int*iptr1,iptr2;/iptr1指针变量,iptr2整型变量int*iptr1,*iptr2;/两个指针变量,地址和指针的关系int x,*ptr;x=3;ptr=/x=11,二、指针变量的赋值与变量定义一样,定义好指针变量后也可以对它进行初始化,指针变量可以初始化为0、NULL或一个地址。数值为0或者NULL的指针不指任何内容。数值0是可以
4、直接赋给指针变量的唯一整数值。1.在定义指针变量的同时进行初始化赋值,一般格式如下:数据类型*指针名初始地址;,2.定义指针变量后,用赋值语句将其初始化。指针变量名=地址;可以是变量的地址、数组名、函数名等。用变量地址作为初值时,该变量的定义必须在指针初始化之前定义。不能把常量或表达式的地址赋给指针变量。不能将一个非0整数直接赋给指针变量,但可以赋整数值0,表示该指针为空指针。例如:int*p;p=0;p为空指针,不指向任何地址。,3.允许声明指向 void 类型的指针,该指针可以被赋予任何类型对象的地址。例如:void*general;int*point;int i;general=,例5.
5、2、阅读如下程序:源程序清单:#includeusing namespace std;void main()int x;int*p;int*q;int a=3;int*pa=,#include using namespace std;void main()int x=3,*ptr=/变量x的地址,三、指针变量的使用例5.3、阅读如下程序:源程序清单:#includeusing namespace std;void main()int x,*p;p=,指针在使用前要进行初始化或赋值,指针未赋值将非常危险。#include using namespace std;void main()int x=
6、26;int*ptr;*ptr=58;/此时ptr是一个随机地址coutxendl;很可能已经破坏了另一变量的值,甚至修改了函数的返回地址等。,5.3、简单变量与指针指针的类型是它所指向变量的类型。指针值不是整型数,在使用中必须类型匹配。如:int x=26;int*ptr=表示将变量x的地址值作为一个整型数赋给变量*ptr,即变量x。,因为指针是有类型的,所以给指针赋值不但要是一个地址,而且应该是一个与该指针类型相符的变量的地址。或者说指针的类型是它所指向变量的类型。float f=34.5,*fptr=/error:浮点指针赋给整型指针将一个指针赋值给另一个指针,结果是两个指针指向一个相
7、同的地址单元。,例5.4、阅读如下程序:源程序清单:#includeusing namespace std;void main()int x,*p;x=3;p=,例5.5、输入a和b两个整数,运用指针技术按先大后小的顺序输出a和b。源程序清单:#include#include using namespace std;void main(void)/利用间接访问方式来操作,int a,b;int*p1=,指针变量的运算指针的算术运算指针加一,减一运算是指向下一个或前一个数据。如:y=*px+相当于y=*(px+)/px为一指针指针与整数的加减运算指针 p 加上或减去 n,其意义是指针当前指向位置
8、的前方或后方第 n 个数据的地址。这种运算的结果值取决于指针指向的数据类型。,pb-1,pb,pb+1,pb+2,*(pb-1),*pb,*(pb+1),*(pb+2),int*pb,#include using namespace std;void main()int n=20,*ptr=,关系运算表示所指变量在内存中的位置关系如:两个指针变量指向同一个数组中的元素时,其关系运算的结果表明了这两个指针变量所指向的数组元素的先后关系char a10;char*p1,*p2;p1=a+2;p2=a+4;p1+;p2-;指针可以和零之间进行等于或不等于的关系运算。例如:p=0;/表示空指针,例5.
9、5、编写一交换两个整型变量值的函数,并写一主函数测试。#include using namespace std;void swap(int*x,int*y)int t;t=*x,*x=*y,*y=t;void main()int a=1,b=2;cout交换前:a=a,b=bendl;swap(,5.4、一维数组与指针数组名可以拿来初始化指针,数组名就是数组第一个元素的地址,即对于数组a,有a=对第i个元素可表示成以下四种:ai、*(a+i)、iptri、*(iptr+i)这四个等价关系使得数组与指针相互转换非常灵活。,与上面相对应的有下面四个地址等价关系:&ai a+i iptr+i&ipt
10、ria+i表示第i个数组元素的地址,iptr+i也同样是指向数组a的第i个数组元素。,相互等价,例5.6、求数组元素的和#includeusing namespace std;int sum1,sum2,sum3,sum4,sum5,*iPtr;int iArray=1,4,2,7,13,32,21,48,16,30;void main()int size,n;size=sizeof(iArray)/sizeof(*iArray);/sizeof(iArray):数组iArray所占字节数/sizeof(*iArray):数组元素类型所占字节数 for(n=0;nsize;n+)sum1+=i
11、Arrayn;/方法1,iPtr=iArray;/方法2for(n=0;nsize;n+)sum2+=*iPtr+;iPtr=iArray;/方法3for(n=0;nsize;n+)sum3+=*(iPtr+n);iPtr=iArray;/方法4for(n=0;nsize;n+)sum4+=iPtrn;/方法5for(n=0;nsize;n+)sum5+=*(iArray+n);coutsum1=sum1,sum2=sum2,sum3=sum3,sum4=sum4,sum5=sum5endl;,例5.7、阅读如下程序:源程序清单:#include using namespace std;voi
12、d main()char a10=abcdefghi;char*p1,*p2;p1=a;p1+=2;,p2=a+4;/指针变量p2,直接由数组名加上4,指向数组的第五个数组元素的内存单元 if(p1p2)coutp1所指向的数组元素在p2所指向的数组元素前面!endl;else coutp1所指向的数组元素在p2所指向的数组元素后面!endl;p1+;p2-;if(p1=p2)coutp1和p2同时指向数组中的同一个元素且元素值为:*p1endl;else coutp1和p2没有指向数组中的同一个元素!endl;,例5.8、利用指针技术,将键盘输入的N个整数按相反的顺序存放并输出。思路分析:分
13、别取出数组最前面和最后面的元素,进行交换,即a0与aN-1交换;然后再分别取出a1与aN-2交换;直到交换完毕。,源程序清单:#include#include using namespace std;int main(void)int a10,i,j,temp,*p;cout*p;p=a;,for(i=0,j=10-1;ij;i+,j-)temp=*(p+i);*(p+i)=*(p+j);*(p+j)=temp;for(p=a;pa+10;p+)coutsetw(4)*p;coutendl;return 0;,例5.9、把一个整数插入到一个由小到大的有序整数序列中,并仍然保持由小到大的顺序。设
14、有10个整数按由小到大的顺序存放在数组a中,待插入的数放在变量x中。#include#include using namespace std;void main(void)const int N=10;int aN+1,p,x,*t;,cout*t;coutx;t=a;p=0;while(x*(t+p),例5.10、从键盘输入整数集合a、b的元素个数和各个元素的值(不相同),计算并输出其交集。#include using namespace std;#include void main(void)const int M=20,N=10;int aM,bN,cM;int d,e,f=0,*pa,
15、*pb,*pc;,coutd;cout*pa;coute;cout*pb;,for(pa=a,pc=c;paa+d;pa+)for(pb=b;pbb+e;pb+)if(*pa=*pb)*pc+=*pa;f+;break;cout交集c的各个元素依次为:endl;for(pc=c;pcc+f;pc+)coutsetw(3)*pc;coutendl;,例5.11、从键盘输入整数集合a、b的元素个数和各个元素的值(不相同),计算并输出其并集。#include using namespace std;#include void main(void)const int M=20,N=10;int aM,
16、bN,cM+N;int d,e,f=0,*pa,*pb,*pc;,coutd;cout*pa;coute;cout*pb;,for(pa=a,pc=c;pa=a+d)*pc+=*pb;f+;cout“并集c的各个元素依次为:endl;for(pc=c;pcc+f;pc+)coutsetw(3)*pc;coutendl;,例5.12、编程实现将一个数组中的数据按相反顺序存放。思路分析:用一个子函数实现按相反顺序存放,主函数调用该子函数实现按相反顺序存放。#include using namespace std;void invert(int*p,int n)int i,j,temp;for(i=
17、0,j=n-1;ij;i+,j-)temp=*(p+i);*(p+i)=*(p+j);*(p+j)=temp;,int main(void)int a10,i;coutai;invert(a,10);for(i=0;i10;i+)coutaiendl;return 0;,5.5、二维数组与指针例5.13、利用指针技术,输出如下二维数组各元素的值。inta34=1,2,3,4,5,6,7,8,9,10,11,12源程序清单1:#include#include using namespace std;void main(void),int a34=1,2,3,4,5,6,7,8,9,10,11,1
18、2;int*p;for(p=a0;pa0+12;p+)if(p-a0)%4=0)coutendl;coutsetw(4)*p;coutendl;,源程序清单2:#include#include using namespace std;void main(void)int a34=1,2,3,4,5,6,7,8,9,10,11,12;int*p3;int i,j;,for(i=0;i3;i+)pi=ai;for(j=0;j4;j+)coutsetw(4)*(pi+j);coutendl;,例5.14、利用指针技术,求55方阵主对角线的和。思路分析:55的方阵用二维数组a55表示,定义一个指针数组*p5,来操作数组;求主对角线的和,先找到主对角线上的元素,应满足条件行号等于列号,再进行累加。源程序清单:#include using namespace std;void main(void),int a55;int*p5;int i,j,sum=0;cout*(pi+j);,for(i=0;i5;i+)pi=ai;for(j=0;j5;j+)if(i=j)sum=sum+*(pi+j);cout方阵的对角线之和为:sumendl;,