C++大学基础教程第六章.ppt
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C++ 大学 基础教程 第六
- 资源描述:
-
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,C+,大学基础教程,第,6,章 指针和引用,2026/3/4 周三,1,指针(,Pointer,)是,C+,和,C,的一种数据类型。很多其他高级语言也有类似的数据类型。,引用(,Reference,)则是,C+,所特有的一种数据类型。,2026/3/4 周三,2,第六章 指针和引用,6.1,指针的概念,6.2,指针的运算,6.3,指针和函数,6.4,指针和字符串,6.5,通过指针访问数组,6.6,指针访问动态内存,6.7,引用概念,2026/3/4 周三,3,6.1,指针的概念,2026/3/4 周三,4,6.1.1,指针和指针变量,指针是变量的,地址,例如,定义整型变量,a,,,a,的地址就是,一个指针。,直接指定内存某个地址开始(如,0 x00430100,),存放指针的变量就是指针变量。,2026/3/4 周三,5,6.1.1,指针和指针变量,当声明了一个指针变量后,确定了三件事:,1.,变量本身在内存中所分配的地址和字节数,(,4,个,),2.,系统允许的地址范围,及地址单元内可以存放的内容,3.,指针变量可以进行的运算,访问指针变量时,只能看到地址,通过这个地址访问地址单元中的内容,这样的访问称为对于内存单元的,间接访问,。,2026/3/4 周三,6,6.1.2,指针变量的声明和初始化,指针变量声明的格式是:,类型名,*,变量名,1,*,变量名,2,;,例如:,int*va1,*va2;,char*ch1,*ch2;,指针变量在声明后,变量的值(地址)是随机的。,这样的指针变量是不能安全的使用的,2026/3/4 周三,7,6.1.2,指针变量的声明和初始化,在声明指针变量时的,“,*,”,,有两个含义:,声明变量,va1,、,ch1,、,ch2,都是指针变量;,说明变量,va1,的类型是(,int*,)型,即,指向整型变量的指针,。,ch1,和,ch2,的类型是(,char*,)型,指针变量都是有类型的,-,所指定的地址单元中存放的数据的类型,2026/3/4 周三,8,6.1.2,指针变量的声明和初始化,指针变量必须,初始化后,才能,安全使用,声明指针变量时进行初始化的格式:,类型名,*,指针变量名,=&,变量名,;,char ch1=,Y,ch2=,A,;,char*pch1=,2026/3/4 周三,9,6.1.2,指针变量的声明和初始化,赋值方式进行初始化:,int i1=,Y,i2=,A,;int*pi1,*pi2;,pi1=,pi2=,没有初始化的指针变量不可以使用,(,编译系统会给出警告,而运行时会出现错误,),2026/3/4 周三,10,6.2,指针的运算,2026/3/4 周三,11,6.2,指针的运算,表,6.1,指针的运算,2026/3/4 周三,12,6.2.1,指针的赋值运算,指针的赋值,:,地址的赋值,同类型变量的地址,同类型的已经初始化的指针变量;,其他同类型的指针,用,0,或者,NULL,赋值,“,空指针,”,,即不指向任何的内存物理地址,不同类型的指针不可以互相赋值,在指针赋值时,不存在类型自动转换的机制,2026/3/4 周三,13,例,6.1,观察以下指针赋值运算的结果。如果将注释去掉,结果将如何?,#include,using namespace std;,void main(),int va1=100,*pva1;int*pva2=NULL;,float vf1=A,*pvf1,*pvf2;,coutvalue of pva2 is pva2endl;,pva1=,pvf1=pvf2=,coutpva1 ,coutpvf1 pvf2endl;,/pvf1=pva1;,value of pva2 is 0 x00000000,0 x0012FF7C 0 x0012FF7C,0 x0012FF74 0 x0012FF74,注释去掉会出现编译错误,2026/3/4 周三,14,6.2.2,间接引用运算,间接引用运算符,“,*,”,:,一元运算符,和指针变量连用,对指针所指向的内存地址单元进行间接访问,使用的格式:,*指针变量,如果指针变量,iptr,指向整型变量,va,*,iptr,就是变量,va,的内容,2026/3/4 周三,15,例,6.2,对变量的直接访问和间接访问,#include,using namespace std;,void main(),char ch1=a,*ch;,int k1=100;,ch=/,指针,ch,指向变量,ch1,cout*ch=*chendl;/,间接访问,*,ch=B;,coutch1=ch1endl;/,直接访问,ch1=k1;,cout*ch=*chendl;/,间接访问,运行结果,:,*ch=a,ch1=B,*ch=d,2026/3/4 周三,16,例,6.3,观察对这种指针变量间接访问的结果。,#include,using namespace std;,void main(),int va=100,*pva,*ppva;,/ppva,是指向指针的指针,int k1=100;,pva=,cout*pva=*pvaendl;,/,间接访问结果是整型数,ppva=,cout*ppva=*ppvaendl;,/,间接访问结果是地址,coutpva=pvaendl;,/,就是指针,pva,的内容,运行结果,:,*pva=100,*ppva=0 x0012FF7C,pva=0 x0012FF7C,2026/3/4 周三,17,6.2.2,间接引用运算,2026/3/4 周三,18,6.2.3 指针的算术运算,可以进行的只有,加法和减法,-,和整数,n,做加法或者减法,指针,p,和整数,n,相加(相减)的含义是指向当前指向位置,p,的前方或后方第,n,个数据的地址。,2026/3/4 周三,19,例6.4 通过指针的间接访问,输出下标为偶数的数组元素的值。,#,include,using namespace std;,void main(),int k110=11,24,37,44,58,66,79,86,93,108,*k;,k=,for(int i=0;i10;i=i+2),coutk1i=*(k+i);,coutendl;,运行结果,:,K10=11 k12=37.,数组第一个元素(下标为,0,)的地址赋值给指针,k,每次循环,指针加,2,2026/3/4 周三,20,6.2.3 指针的算术运算,指针和指针的,直接加法没有意义,指针和指针的,减法可以,进行,-,求出两个指针之间可以存放几个指定类型的数据,不允许用一个整数减一个指针,2026/3/4 周三,21,6.2.4,指针的关系运算和逻辑运算,同类型,的指针,可以,进行关系运算,进行指针,“,大于,”,、,“,小于,”,的比较,是判定指针在内存中的相对位置,指针和一般的整数比较没有意义,也不允许,惟一可以和指针比较的整数是0。判定指针是不是空指针,2026/3/4 周三,22,6.2.5,void,类型指针,void,类型的指针就是,“,无类型,”,指针:,void*,指针名;,存放的也是内存的地址,但不指定这个地址单元内的数据的类型,2026/3/4 周三,23,6.2.5,void,类型指针使用要点,-,任何指针都可以赋值给,void,指针,赋值后的,void,指针的类型仍然是,void,-void,指针不可以赋值给其他任何类型的指针,-void,指针不可通过间接引用访问内存中数据,-,必须进行指针类型的强制转换,才可以使用指针间接引用访问内存数据,2026/3/4 周三,24,例,6.5,使用,memcpy,通用复制函数复制数组,原型,void*memcpy(void*dest,const void*,size),#,include,using namespace std;,#include,void main(),char src10=012345678;,char dest10;,char*pc=(char*)memcpy(dest,src,10);,cout pc endl;,int s13=1,2,3;,int d13;,int*pi=(int*)memcpy(d1,s1,12);,cout*pi *(pi+1)*(pi+2)endl;,运行结果,:,012345678,1 2 3,复制字符数据,10个字节,复制整型数据,12个字节,2026/3/4 周三,25,6.2.5,void,类型指针,void,类型指针应用:,显示字符指针的内容,其他指针直接用,cout,语句输出地址值,而字符指针输出的是字符串,将字符指针强制转换为,void,指针,cout,语句输出便是地址值,例:,char*pch=Hello C+;,coutpchendl;,cout(void*)pchendl;,2026/3/4 周三,26,指针是地址,int*p;,p=,*p=100;b=*p+2;,2026/3/4 周三,27,6.3,指针和函数,2026/3/4 周三,28,6.3 指针和函数,在程序设计中,指针有很多应用,其中之一就是,作为函数的参数,,形成了,C+,函数调用中的另一种调用方式:,地址调用,2026/3/4 周三,29,6.3.1 指针作为函数的参数,实现地址调用,必须满足以下条件:,函数的,形式参数是指针变量,;,函数的,实参数是内存的地址,(可以是,数组名,、,变量的地址,、用变量地址初始化的,指针,),形参指针类型和实参地址,类型必须相同,2026/3/4 周三,30,6.3.1 指针作为函数的参数,实参传递给形参的是内存的地址,所以形参指针指向实参变量,形参指针,通过间接引用,,,直接访问实参变量,(包括改变实参变量的值),函数调用后,改变了实参,如果有多个实参,就可以有多个实参变量在函数调用中被修改,2026/3/4 周三,31,例,6.6,编写数据交换的函数。,#include,void Swap(int*a,int*b);,void main(),int x(5),y(10);,cout,主函数变量的值:,x=x y=yendl;,Swap(,cout,返回后变量的值:,x=x y=yendl;,void Swap(int*a,int*b),int t;,t=*a;,*a=*b;,*b=t;,cout,函数中完成了交换:,*,a=*a *b=*bendl;,运行结果,:,主函数变量的值:,x=5 y=10,函数中完成了交换:,*,a=10 *b=5,返回后变量的值:,x=10 y=5,变量的地址作为实参数,指针变量作为形式参数,2026/3/4 周三,32,6.3.1 指针作为函数的参数,变量,x,和,y,的地址作实参传递给指针,a,和,b,如图,(,a),通过间接引用,*,a,和,*,b,进行交换,实际上就是,x,和,y,进行交换,如图,(,b),2026/3/4 周三,33,例,6.7,指针变量指向一个数组,#include,using namespace std;,void Move(int*a);,void main(),int x5=10,20,30,40,50,*px=x;,cout,调用前的,*,px=*pxendl;,Move(px);,cout,调用后的,px;,if(px=x)cout,没有变化,,*,px,还是,*,pxendl;,else cout,也向前移动,,*,px,变为,*,pxendl;,void Move(int*a),a=a+1;*a=100;,cout,“,函数中完成了指针,移动:,*,a=*aendl;,运行结果,:,调用前的,*,px=10,函数中完成了指针移动:,*,a=20,调用后的,px,没有变化,*,px,还是,10,指针作为实参数,指针变量作为形式参数,2026/3/4 周三,34,6.3.3 传递参数的保护:指针和常量,通过数组名地址调用,,可以,改变实参数组内容,但有时并不需要改变数组的值,例如,在调用一个求数组最大值的函数时,就不希望数组的值发生变化,希望在函数中能够限制对数组元素的修改,使用,常指针,可以达到这个目的,2026/3/4 周三,35,6.3.3 传递参数的保护:指针和常量,常指针,是指向常量的指针,(,Pointer to Constant data),规定指针所指向的内容不可以通过指针的间接引用来改变,。,常指针说明的格式是:,const,类型名*指针名;,例如:,const int*ptint;,指针,ptint,的类型是(,const int*),,即指向一个恒定的整型数,2026/3/4 周三,36,例,6.10,常指针示例。观察以下程序的运行。,#include,using namespace std;,void main(),int ia=10,ib=20;,const int*ptint;,ptint=,/,用,ia,地址初始化,cout*ptintendl;,ptint=,/,改变为,ib,的地址,ib=ib+100;,/ib,本身仍然可以改变,cout*ptintendl;,/*ptint=100;,/,语句错误:左值是常量,运行结果,:,10,120,常指针声明,注释去掉会出现编译错误,2026/3/4 周三,37,6.3.3 传递参数的保护:指针和常量,指针常量,(,Pointer constant,),指针本身是常量,(,地址是常量,),不可以改变,指针常量声明的格式:,类型名,*,const,指针名,=,初值,;,char ch,*const ptch=,数组名是数组的首地址,-,数组名是指针常量,2026/3/4 周三,38,例6.11 指针常量示例。指出以下程序的错误。,#include,using namespace std;,void main(),int a=10,b=100;,int*const pa=,/pa,是指针常量,cout*paendl;,*pa=20;,/,指针常量的间接引用是允许的,coutaendl;,pa=,const int c=50;,int*const pc=,错误语句注释掉后运行结果,:,10,20,语句有错:常量不能当左值,语句有错,地址类型不同,不能用常量地址初始化指针常量,2026/3/4 周三,39,例,6.12,用常指针作形参,函数,printString,可以输出数组的内容,不可以对数组修改。,#include,using namespace std;,void printString(const char*);,void main(),char phrase=C+is a programming language;,cout The string is:n;,printString(phrase);cout endl;,/main,函数结束,void printString(const char*Ptarray),while(*Ptarray),cout *Ptarray+;,不使用常指针也是可以完成打印。但是没有保护了。,数组名作实参数,常指针作形式参数,2026/3/4 周三,40,6.4,指针和字符串,2026/3/4 周三,41,6.4.1 字符串处理的两种方式,字符串常量,:双引号括起,,0,结束 如:,This is a string。,字符串常量有自己固定的首地址,如果将字符串常量的首地址看成是指针,这种指针既是常指针,也是指针常量。,2026/3/4 周三,42,6.4.1 字符串处理的两种方式,处理字符串两种方式:,数组方式,和,指针方式,数组方式,是将字符串存入字符数组:,char string_array,=What,s a nice day!;,指针方式,是用字符串常量来初始化一个字符指针:,char,*,string_pt=What,s a nice day!;,2026/3/4 周三,43,6.4.1 字符串处理的两种方式,指针常量不能放在等式左边,运行时会出错,2026/3/4 周三,44,6.4.2,字符串操作函数,实参数:字符数组名、已经初始化的字符指针,字符串常量,目的串必须是可写的。,2026/3/4 周三,45,例6.14,strcpy,和,strncpy,的比较。,#include,void main(),int n;,char*array1=Happy Birthday to You;,char array3 15;char array2 25;,strcpy(array2,array1);,cout The string in array1 is:array1,nThe string in array2 is:array2 n;,/*strcpy(array3,array1);,coutarray3endl;*/,n=sizeof(array3);,strncpy(array3,array1,n-1);/,复制,array1,的,n-1,个字符,array3 14 =0;/,添加,0,到,array3,cout The string in array3 is:array3 endl;,不包括提示的运行结果,Happy Birthday to You,Happy Birthday to You,Happy Birthday,复制,array1,到,array2,,没有问题,复制,array1,到,array3,,空间不够,有运行错误,按实际数组大小,复制,array1,到,array3,,没有问题,2026/3/4 周三,46,6.5,通过指针访问数组,2026/3/4 周三,47,6.5 通过指针访问数组,指针和数组有天然的联系,数组名就是地址,,也就是某种类型的指针,虽然一维数组名和二维数组名都是地址,都可以看作是某种指针,但是指针的类型是不同的,通过指针访问一维数组和二维数组的方法是不同的,2026/3/4 周三,48,6.5.1 通过指针访问一维数组,必须声明和数组类型相同的指针,并用数组名初始化指针:,int A10,*pa=A;,多种方式访问数组元素,数组名和下标,如,A0、A4,指针和下标,如,pa0、pa4,指针加偏移量的间接引用,如,*(pa+4),数组名加偏移量的间接引用,如,*(A+4),指针自加后的间接引用,如,*,pa+,2026/3/4 周三,49,例6.15 求数组内所存放的字符串的长度,void main(),char ChArray=This is a string.,*ptch;,int i,j,k,offset1,offset2;,ptch=ChArray;,/,指针初始化,for(i=0;,ChArrayi,!=0;i+);,coutThe length of the string is:iendl;,for(j=0;,ptchj,!=0;j+);,coutThe length of the string is:jendl;,for(offset1=0;,*(ChArray+offset1),!=0;offset1+);,coutThe length of the string is:offset1endl;,for(offset2=0;,*(ptch+offset2),!=0;offset2+);,coutThe length of the string is:offset2endl;,for(k=0;,*ptch+,!=0;k+);,coutThe length of the string is:kendl;,运行结果都相同,方式1,数组名下标,方式2:指针和下标,方式3:数组名加偏移量的间接引用,方式4:指针加偏移量的间接引用,方式5:指针自加的间接引用,2026/3/4 周三,50,例6.16求整型数组的平均值,显示数组元素和平均值。,void main(),int intArray10=8,11,23,34,45,56,65,78,86,97,*ptint;,int i,num,sum;float average;,ptint=intArray;,sum=0;,num=sizeof(intArray)/sizeof(*intArray);,for(i=0;inum;i+),sum=sum+*ptint+;,average=(float)sum/num;,ptint=intArray;,cout,数组元素是:,n;,for(i=0;inum;i+),cout*ptint+;,cout,“,n,平均值是:,”,averageendl;,运行结果:,数组元素是:,8 11 23 34 45 56 65 78 86 97,平均值是:,50.3,指针初始化,求数组元素的数目,求平均值,指针再次初始化,输出数组元素和它们的平均值,2026/3/4 周三,51,6.5.2 通过指针访问二维数组,二维数组可以看成是一维数组的一维数组,二维数组名也是地址(指针),但和一维数组名有不同的类型,对一维数组,A5,数组名,A,的地址,是第一个元素,A0,的地址,指针的类型是指向数组元素的指针,A+1 A1,的地址,2026/3/4 周三,52,6.5.2 通过指针访问二维数组,对二维数组,B34,数组名,B,的地址,一维数组,B0,的地址,指针的类型是指向一维数组的指针,B+1,一维数组,B1,的地址,2026/3/4 周三,53,6.5.2 通过指针访问二维数组,定义指向一维数组的指针时,必须指出一维数组的大小,声明格式如下:,类型名(*指针变量名)一维数组大小;,例如:,char(*ptchb)4,(*ptchc)2;,ptchb=B;ptchc=C;,2026/3/4 周三,54,6.5.2 通过指针访问二维数组,指向一维数组的指针具有的,特征,:,二维数组名是指向一维数组的指针,不指向数组元素,指针加,1,是指向下一个一维数组的指针,指向一维数组的指针的间接引用的结果仍然是地址,,即,*,ptchb,仍然是地址,为一维数组,B0,第一个元素,B00,的地址,*,ptchb,是数组元素的地址,,*,ptchb,就是数组元素的值,访问二维数组第,i,行第,j,列元素,:,*(*(,指针名,+,i)+j),2026/3/4 周三,55,例6.17比较指向一维数组的指针和指向数组元素的指针,void main(),short B34,C32;,short(*ptshb)4,(*ptshc)2;,ptshb=B;ptchc=C;,cout,比较不同的指向一维数组指针的差别,n;,coutptshb,的地址是:,ptshbn;,coutptshb+1,的地址是:,ptshb+1n;,coutptchc,的地址是:,ptshcn;,coutptchc+1,的地址是:,ptshc+1n;,比较不同的指向一维数组指针的差别,ptshb,的地址是:,0,x0012FF68,ptchb+1,的地址是:,0,x0012FF70,ptchc,的地址是:,0,x0012FF5C,ptchc+1,的地址是:,0,x0012FF60,B,的第0行地址,B,的第1行地址,C,的第0行地址,C,的第1行地址,2026/3/4 周三,56,cout,不同类型的指针,n;,coutptshb,的地址是:,ptshbendl;,cout*ptshb,的地址是:,*,ptshbendl;,cout*ptshb+1,的地址是:,*,ptshb+1endl;,coutB01,的地址是:,&,B01endl;,/cout,“,ptchb,和,*,ptchb,相等吗?,”,(,ptchb=*ptchb)endl;/,有语法错误,类型不同,cout*ptshb+1,和,&,B01,相等吗?,;,if(*ptshb+1=,不同类型的指针,ptshb,的地址是:,0,x0012FF68,*ptshb,的地址是:,0,x0012FF68,*ptshb+1,的地址是:,0,x0012FF6A,B01,的地址是:,0,x0012FF6A,*ptshb+1,和,&,B01,相等吗?,Yes,B,的第0行地址,B,的第0行第0列 元素的地址,B,的第0行第1列 元素的地址,B,的第0行第1列 元素的地址,2026/3/4 周三,57,例6.18 用单循环程序,求二维数组元素的平均值。,void main(),int Array34,=32,42,12,25,56,76,46,53,76,89,96,82,(*pt)4;,int sum,j;,float average;,sum=0;,pt=Array;,j=sizeof(Array)/sizeof(*Array);,for(int i=0;ij;i+),sum=sum+*(*pt+i);,average=(float)sum/j;,cout,数据的平均值等于:,averageendl;,运行结果:,数据的平均值等于57.0833,指向一维数组指针的初始化,求数组元素的数目,,*Array,就是元素,Array00,数组求和,求平均值,输出平均值,2026/3/4 周三,58,一维数组:,int intArray2=8,11,*ptint;,sum=sum+*ptint+;,二维数组:,int A23,=32,42,12,25,56,76,(*pt)3;,sum=sum+*(*(pt+i)+j);,2026/3/4 周三,59,6.6,指针访问动态内存,2026/3/4 周三,60,6.6 指针访问动态内存,动态内存,:,在程序执行时才可以申请、使用和释放的内存,存放动态数据的区域称为,“,堆,”,,动态内存也称为,堆内存,动态内存不能通过变量名来使用,只能通过指针来使用,2026/3/4 周三,61,6.6.1 动态内存的申请和释放,C+,中通过运算符,new,申请动态内存,运算符,delete,释放动态内存,new,的使用格式:,new,类型名(初值),int*p;,p=new int(3);,申请成功:返回指定类型内存的地址,申请失败,:,返回,NULL,指针,2026/3/4 周三,62,6.6.1 动态内存的申请和释放,运算符,delete,释放动态内存,delete,运算符使用格式:,delete,指针名;,delete p;,new,与,delete,应该成对出现,2026/3/4 周三,63,6.6.2 动态数组空间的申请和释放,申请动态数组要加上数组的大小:,一维:,new,类型名常量表达式;,注意:动态申请数组空间时,不可以对数组进行初始化,二维:,int(*pi_marray)4;,pi_marray=new int34;,释放动态数组空间都用相同的表达式:,delete;,2026/3/4 周三,64,6.6.3,内存泄漏和指针悬挂,内存泄漏,动态申请的内存空间,没有正常释放,但也不能继续使用的情况。如:,char*ch1;,ch1=new char(A);,char*ch2=new char;,ch1=ch2;,原来为,ch1,所申请的存放字符,A,的空间就不能再使用了,产生了内存泄漏,2026/3/4 周三,65,6.6.3,内存泄漏和指针悬挂,指针指向一个已经释放的空间,即指针悬挂,char*ch1,*ch2;,ch1=new char;,ch2=ch1;,*ch2=B;,delete ch1;,指针,ch2,指向了一个已经释放的地址空间,-,指针悬挂,用,delete ch2;,语句来释放,ch2,所指向的空间,会出现运行错误,2026/3/4 周三,66,6.7,引用概念,2026/3/4 周三,67,6.7,引用概念,引用(,Reference,),是,C+,中新引入的概念,是,C,语言中不存在的数据类型,引用是,变量或者其他编程实体(如对象)的,别名,因此引用不可以单独定义,如图,6.4(,a),:变量,A,在内存中有自己的地址,而,A,的引用,B,实际上就是变量,A,,,只是,A,的另外一个名字,2026/3/4 周三,68,6.7.1,引用的声明和使用,引用通过运算符&来定义:,类型名 ,变量名必须已经定义,和引用的类型必须相同,int someInt;,int,必须注意:引用必须在声明的时候就完成初始化,不可以先声明引用,然后再用另一个语句对它初始化。,2026/3/4 周三,69,改进,C,中函数的形参定义为指针型参数时所带来的不安全性,int add(int*x,int*y),*x=*x+*y;,return*x;,int add(int&x,int&y),x=x+y;,return x;,改为,2026/3/4 周三,70,6.7.1,引用的声明和使用,引用的特点:,引用不能独立存在,它只是其他变量的别名,引用必须在声明的同时初始化,引用一旦定义,引用关系就不可以更改,B,是,A,的引用,就不可能是其他变量的引用,引用的类型就是相关的变量的类型,引用的使用和变量的使用相同,2026/3/4 周三,71,例,6.22,引用的使用。观察以下程序的结果。,void main(),int intA=10;,int,cout,“,引用的值和,相关变量值相同,:,refA=,refAendl;,refA=5;,cout,“,引用的变化,则相关变量也变化:,intA=,intAendl;,cout,“,引用的地址和相关变量地址相同:,intA,的地址,&,intAendl;,cout,“,引用的地址和相关变量地址相同:,refA,的地址,&,refAendl;,引用的值和相关变量值相同,:,refA=10,引用的变化,则相关变量也变化:,intA=5,引用的地址和相关变量地址相同:,intA,的地址,0,x0012FF7C,引用的地址和相关变量地址相同:,refA,的地址,0,x0012FF7C,2026/3/4 周三,72,例6.23 指针的引用。,void main(),int intA=10,intB=20;,int*pti=,int*,cout,“,指针的引用可以访问指针所指的变量,:*,refi,=*refiendl;,cout,指针变量原来的值:,pti,=ptiendl;,refi=,cout,“,引用的变化,则相关指针也变化:,pti,=ptiendl;,cout,指针所指的变量值也发生变化:,*,pti,*ptiendl;,指针的引用可以访问指针所指的变量,:*,refi=10,指针变量原来的值,:,pti=0 x0012FF7C,引用的变化,则相关指针也变化,:,pti=0 x0012FF78,指针所指的变量值也发生变化:,*,pti,20,2026/3/4 周三,73,6.7.1,引用的声明和使用,如果不希望通过引用来改变相关的变量的值,可以定义常引用:,const,类型名,例如:,int someInt=10;,const int,const_refA,就是常引用。不可以通过,const_refA,来改变,someInt,变量的值,2026/3/4 周三,74,6.7.2 通过,引用传递函数参数,引用,使用最多的场合是,作为,函数的,形式参数,引用作为函数的形参有以下,特点,:,形参,实参是相同类型的,变量,引用作为形参,参数传递属于,地址传递,引用作为形参,在函数中并不产生实参副本,是,同一个实体,函数对引用的操作,也是对实参变量的操作,函数调用可以改变实参数的值,2026/3/4 周三,75,例6.24 用引用作为形式参数,交换两个实参数。,#include,using namespace std;,void swap_1(int&x,int&y),/,引用作为形式参数,int j;j=x;x=y;y=j;,void main(),int a=12345,b=54321;,cout,函数调用前:,a=,a,b=,bendl;,swap_1(a,b);,/,变量作为实参数,cout,函数调用后:,a=,a,b=,bendl;,函数调用前,:,a=12345 b=54321,函数调用后,:,a=54321 b=12345,2026/3/4 周三,76,函数返回多个值 (可以用地址,还可用引用),float Length(int r),return 2*PI*r;,float Area(int r),return PI*r*r;,给定半径,计算面积、周长,Void CalculateCircle(int r,float&length,float&area),length=2*PI*r;,area=PI*r*r;,main(),int r=10;float l,s;,CalculateCircle(r,l,s);,2026/3/4 周三,77,6.7.2 通过,引用传递函数参数,使用引用作为形式参数还需要,注意,:,如果实参数需要保护,使用,“,常引用,”,作为形参,用引用作形参和用变量作形参是有区别的,尽管实参数可能相同,函数,swap(int a,int b),和,swap(int&a,int&b),看起来是两个可以区分的重载函数,但调用相同,:swap(x,y),,无法区分,函数,swap(int a,int b),和,swap(int&a,int&b),不是可以区分的重载函数,2026/3/4 周三,78,6.7.3 用,引用作为函数的返回值,返回引用需,注意,:,返回引用需在函数的返回值类型中加以说明,类型名&函数名(形式参数表),返回引用的返回语句是:,return,变量名;,返回引用实际是返回地址,在使用上,或者直接使用这个地址;或者使用这个地址单元的数据,返回的引用可以作为左值继续操作,而返回的变量值是不可以继续运算的。这是返回引用和返回变量值在使用上的主要区别。,2026/3/4 周三,79,例6.25 引用作为函数返回值。,#include,using namespace std;,int,void main(),int pa=10,pb;,cout,输出,1,:,pb=,(pb=fun(pa)endl;,int,cout,输出,2,:,pc=pcendl;,cout,输出,3,:,+,fun(pa)endl;,int&fun(int&pf),pf=pf+10;,coutpfendl;,return pf;,返回引用的函数原型,使用返回引用的变量值,使用返回引用的地址,返回的引用继续加,1,返回引用的函数,20,输出,1,:,pb=20,30,输出,2,:,pc=30,40,输出,3,:,41,2026/3/4 周三,80,总结,指针变量的特点是可变性,即一个指针变量内的地址是可变的。所以,通过一个指针变量,就可以访问一个数组。,引用的特点是不变性,一个变量的引用就只能和这个变量联系在一起。,本章还介绍了函数调用的另一种方式:地址调用。具体又分为指针调用和引用调用。,2026/3/4 周三,81,展开阅读全文
咨信网温馨提示:1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。




C++大学基础教程第六章.ppt



实名认证













自信AI助手
















微信客服
客服QQ
发送邮件
意见反馈



链接地址:https://www.zixin.com.cn/doc/13347322.html