版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++程序设计及项目实践1第9章 指针及引用
指针是C和C++中重要的技术,许多重要的函数及功能都是建立在指针基础上。有一些功能必须通过指针才能实现,比如先前在定义数组的时候需要使用常量来定义数组的长度,也就是使用数组的时候必须提前分配一个固定长度的空间,这在程序运行过程中,可能会导致程序占用多余的内存而浪费,若使用指针相关技术,则程序可以动态分配内存:程序需要多大数组空间则分配相应容量的空间,不再使用这部分空间的时候则可以进行回收,那么程序运行的性能会显著提升。C++程序设计及项目实践第9章 指针及引用
29.1指针基础9.2指针与函数9.3指针与数组9.4内存动态分配9.5单项链表9.6引用9.7const对指针及引用的写保护9.8应用9.9本章小结C++程序设计及项目实践39.1指针基础9.1.1内存地址及指针9.1.2指针变量定义9.1.3指针变量使用9.1.4void指针9.1.5NULL指针9.1.6指向指针的指针C++程序设计及项目实践49.1.1内存地址及指针程序中定义的变量在编译及运行时会分配一个内存单元,该内存单元的容量根据变量类型占有一定数量的字节(使用sizeof运算符即可以获得该变量的字节数)。所以每一个变量都拥有一个内存地址,该地址可以用取值运算符”&”获得。比如,程序中若定义了整型变量i:inti=3;则i将会被分配一个4字节的空间,该空间内存储的值为3,其地址可以用&i获得,对于其他类型的变量,也可以用类似的方法获得其内存地址。变量的内存地址称为该变量的指针。C++程序设计及项目实践5例9.1内存地址显示示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06floatf=4.5f;07doubled=6.7;08cout<<"i="<<i<<"\taddress="<<&i<<"\tsize="<<sizeof(i)<<endl;09cout<<"f="<<f<<"\taddress="<<&f<<"\tsize="<<sizeof(f)<<endl;10cout<<"d="<<d<<"\taddress="<<&d<<"\tsize="<<sizeof(d)<<endl;11return0;12}C++程序设计及项目实践69.1.2
指针变量定义可以将某个变量的内存地址,也即是某个变量的指针存放在另外一个专门定义的用来存放指针的变量中,这种可以存放指针的变量称为指针变量。定义指针变量的语法形式:数据类型*指针变量名;若有指针变量定义语句:int*pt;表示定义了一个指针变量pt,*表示该变量pt为指针类型变量,int表示该变量pt中存放的是整型变量的地址,也就是说尽管不同类型变量的内存地址形式上都是十六进制整数,但在定义指针变量时,需要根据指针变量中所预备指向的内存地址存放的数据类型来确定指针变量的数据类型,不能混用,比如,若需要一个指针变量pt存放指向double类型变量的指针(内存地址),则需要定义:double*pt;C++程序设计及项目实践7例9.2指针变量定义示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06floatf=4.5f;07doubled=6.7;08int*pti=&i;09float*ptf=&f;10double*ptd=&d;11cout<<"pti="<<pti<<endl;12cout<<"ptf="<<ptf<<endl;13cout<<"ptd="<<ptd<<endl;14return0;15}&i3ptii*ptiC++程序设计及项目实践89.1.3
指针变量使用
定义指针变量,对指针变量赋地址值后,可以通过对指针变量的操作实现一系列复杂功能,其中最经常使用的操作就是通过指针变量读写所指向的原始变量内存空间。通过指针变量访问所指向的内存空间的语法形式如:*指针变量名。其中*运算符形式上是乘法符号,在这里表示指针运算符,也称为间接访问运算符。
使用*指针变量名操作后,可以认为就获得了指针所指向的变量(内存空间),那么将其作为左值可以对指向变量进行赋值,将其作为右值即从指向变量读取值。C++程序设计及项目实践9例9.3指针运算符示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=1;06int*pti;07pti=&i;08cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;09*pti=2;10cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;11i=i+3;12cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;13i=*pti+4;14cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;15*pti=i+5;16cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;17*pti=*pti+6;18cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;19return0;20}C++程序设计及项目实践109.1.4
void指针
可以声明一个数据类型为void的指针变量,void表示数据类型不确定,定义这种类型的指针变量的语法形式为:void*p;
该类型的指针变量可以理解成通用类型的指针,也就是任何数据类型的指针均可以直接赋给void指针,不过当需要使用*p的方式访问指针指向内存值的时候,需要首先转换void指针为具体的数据类型指针方可。C++程序设计及项目实践11例9.4void指针示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06int*pi=&i;07void*vpi=pi;08int*ipi=(int*)vpi;09cout<<*ipi<<endl;10doubled=4.5;11void*vpd=&d;12cout<<*(double*)vpd<<endl;13return0;14}C++程序设计及项目实践129.1.5
NULL指针声明指针变量的时候,如果指针还没有初始化指向需要的变量时,可以将其赋NULL值,表示空指针。大多数编译软件中定义名称常量NULL为0,如果将指针赋为NULL,相当于指针指向地址为0的内存单元,而0地址的内存单元在大多数操作系统中是由操作系统管理,不允许应用程序访问,如果指针指向0,则意味着该指针不指向任何有意义的单元。C++程序设计及项目实践13例9.5NULL指针示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06int*pi;07cout<<"notassignaddress:"<<pi<<endl;08pi=NULL;09cout<<"assignNULLaddress:"<<pi<<endl;10pi=&i;11cout<<"assignusefuladdress:"<<pi<<endl;12return0;13}C++程序设计及项目实践149.1.6
指向指针的指针可以将变量或某个内存的地址存放在指针里,同样的,可以将某个指针的地址存放在另一个指针里,这样就可以构成一个指针的链条,如下图所示。指针的地方变量的地址数值指向指针的指针指针变量定义变量时,内存分配了一个空间,该空间内可以存放该变量对应的数值;声明指针时,可以将该变量的地址存放在指针的内存空间;声明指向指针的指针后,指针的地址可以存放在指针的指针内存空间。这样可以通过对指向指针的指针的二次间接寻址操作,获得原始变量的值。定义指向指针的指针的语法形式为:数据类型**p;C++程序设计及项目实践15例9.6指向指针的指针示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06int*pi=NULL;07int**ppi=NULL;08pi=&i;09ppi=π10cout<<"i="<<i<<endl;11cout<<"*pi="<<*pi<<endl;12cout<<"**pi="<<**ppi<<endl;13return0;14}C++程序设计及项目实践169.2
指针与函数函数的参数可以为基础的整型,浮点型等,也可以是指针类型的。同样,函数的返回值类型也可以为指针类型。另外,由于函数名和变量名类似,在编译之后也拥有一个地址,所以函数也具有指针,可以定义一个函数指针,在某些情况下使用函数指针来调用函数。C++程序设计及项目实践179.2.1
指针作为函数参数在使用整型,浮点型,字符型等数据作为函数参数时,参数从实参传递给形参按照”按值单向传递”规则进行,也就是在函数中对形参作任何修改操作,也不会影响实参。而若通过指针类型数据作为函数参数时,实参传递给形参的是实参的地址,那么对形参的指针运算本质上就是对实参空间的运算。C++程序设计及项目实践18例9.7指针作为函数实参交换数据程序代码:01#include<iostream>02usingnamespacestd;0304voidswap_value(inta,intb)05{06inttmp=a;07a=b;08b=tmp;09}1011voidswap_address(int*pa,int*pb)12{13int*tmp=pa;14pa=pb;15pb=tmp;16}1718voidswap_pointer(int*pa,int*pb)19{20inttmp=*pa;21*pa=*pb;22*pb=tmp;23}2425intmain(){26intx=3;27inty=4;28int*px=&x;29int*py=&y;30cout<<"begin:\t\t&x="<<px<<"\tx="<<x<<"\t&y="<<py<<"\ty="<<y<<endl;31swap_value(x,y);32cout<<"swapvalue:\t&x="<<px<<"\tx="<<x<<"\t&y="<<py<<"\ty="<<y<<endl;33swap_address(px,py);34cout<<"swapaddress:\t&x="<<px<<"\tx="<<x<<"\t&y="<<py<<"\ty="<<y<<endl;35swap_pointer(px,py);36cout<<"swappointer:\t&x="<<px<<"\tx="<<x<<"\t&y="<<py<<"\ty="<<y<<endl;37return0;38}C++程序设计及项目实践19C++程序设计及项目实践209.2.2
指针作为函数返回值函数返回值类型可以为整型,浮点型和用户自定义的类型,比如结构体,枚举,联合体类型等,也可以为指针类型。由于函数中的局部变量随着函数的退出而释放,所以返回局部变量的地址并没有意义,因此,返回的指针必须是能够不受函数退出而影响的指针变量,主要包括全局指针变量,static变量的指针,函数内new分配的指针变量。C++程序设计及项目实践21例9.8指针作为函数返回值示例程序代码:01#include<iostream>02usingnamespacestd;0304int*getStatic(inta,intb)05{06staticintmul=0;07mul=a*b;08return&mul;09}1011int*getNew(inta,intb)12{1314int*sum=newint;15*sum=a+b;16returnsum;17}1819intmain(){20intx=3,y=4;21int*rStatic=getStatic(x,y);22cout<<*rStatic<<endl;23int*rNew=getNew(x,y);24cout<<*rNew<<endl;25deleterNew;26return0;27}C++程序设计及项目实践229.2.3 函数指针函数在编译之后被分配了相应的空间,函数名可以作为这个空间的入口地址看待,因此可以定义函数指针变量,并将该变量指向函数的入口地址,在使用的时候通过函数指针调用函数。定义函数指针的语法如下:函数类型(*函数指针)(函数形参表);这里的函数类型,函数形参表必须和预备指向的函数完全一致。在定义了函数指针之后,需要将函数指针指向特定的函数。函数指针=函数名;在指向函数之后,可以用如下方式调用函数:返回值=函数指针(函数实参);C++程序设计及项目实践23例9.9函数指针示例程序代码:01#include<iostream>02usingnamespacestd;0304intmymax(inta,intb)05{06returna>b?a:b;07}0809intmymin(inta,intb)10{11returna<b?a:b;12}1314intmyfun(intc,intd,int(*pf)(inta,intb))15{16returnpf(c,d);17}1819intmain(){20int(*pfunction)(int,int);21pfunction=mymax;22cout<<pfunction(3,4)<<endl;23inty1=myfun(30,40,mymax);24cout<<y1<<endl;25inty2=myfun(50,60,mymin);26cout<<y2<<endl;27return0;28}C++程序设计及项目实践249.3.1 数组指针数组在内存中被分配了连续的内存空间,数组名代表了这个空间的起始地址,同时数组中的每个元素也分别对应这个空间的某个地址,所以,数组及数组元素均可以用对应的指针指向它们。具体来说:(1)数组的指针就是指向数组的起始地址。(2)数组元素的指针就是指向具体数组元素的地址,数组的指针同时也是指向数组中第一个元素的指针。(3)当用某个指针指向数组中元素时候,可以对指针变量进行自增,自减,加,减,比较等运算。C++程序设计及项目实践25例9.10数组指针遍历程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05constintLEN=5;06inta[LEN];07int*p=a;08for(inti=0;i<LEN;i++)09{10*p=2*i+1;11p++;12}13p=&a[LEN-1];14while(p>=a)15{16cout<<*p<<'\t';17p--;18}19return0;20}C++程序设计及项目实践269.3.2 指针数组数组的元素也可以是指针,这种数组称为指针数组,声明指针数组的语法形式: 数据类型*指针变量[常量];常量为表示数组长度的常量,定义之后,则该数组中的每一个元素都表示为指向该数据类型数据的指针。C++程序设计及项目实践27例9.11指针数组示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05constintLEN=5;06inta[LEN]={1,3,5,7,9};07int*pa[LEN];08for(inti=0;i<LEN;i++)09{10pa[i]=&a[i];11}12for(inti=LEN-1;i>=0;i--)13{14cout<<*pa[i]<<'\t';15}16return0;17}C++程序设计及项目实践289.3.3 字符指针当数组的元素为字符时,可以定义一个指向字符数组的指针,在使用过程中,字符指针和字符数组名有许多类似的地方,尤其是系统提供的一些字符串处理相关的函数,其参数既可以用字符数组名,也可以用字符指针。C++程序设计及项目实践29例9.12字符指针示例,将字符串转化为大写程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05constintLEN=80;06charstr1[LEN]={0};07char*pstr1=str1;08constchar*str2="iloveC++";09for(inti=0;*(str2+i)!='\0';i++)10{11if(*(str2+i)<='z'12&&*(str2+i)>='a')13{14*pstr1=*(str2+i)-32;15}16else17{18*pstr1=*(str2+i);19}20pstr1++;21}22pstr1=str1;23cout<<pstr1<<endl;24return0;25}C++程序设计及项目实践309.4 内存动态分配指针变量可以指向已定义的变量,也可以指向动态分配的内存空间,这种技术在需要动态使用内存的程序中非常有用,它可以使得运行程序精确控制自己所需要耗费的内存空间。C++程序设计及项目实践319.4.1 基础类型内存动态分配对于常用的整型、浮点型等变量,分配一个单独的内存空间可以用new运算符,语法形式如下:数据类型*指针变量=new数据类型([初始值]);分配的时候将该空间的内存地址赋给指针变量,可以同时赋予分配空间的初始值,初始化值的操作是可选的。对于使用new分配的空间,最后需要将空间释放给系统,释放指针变量需要使用delete运算符,语法形式如下:delete指针变量;C++程序设计及项目实践32例9.13基础指针变量分配与释放示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05int*pi=newint;06float*pf=newfloat(3.5f);07double*pd=newdouble;08*pi=3;09*pd=5;10cout<<*pi<<endl11<<*pf<<endl12<<*pd<<endl;13deletepi;14deletepf;15deletepd;16return0;17}C++程序设计及项目实践339.4.2 可变长数组动态分配先前定义数组的时候需要首先确定数组长度,数组一旦分配,在程序执行全过程中,即使不再需要使用到该数组,数组的空间也不能释放,这会导致内存浪费、影响程序的性能。使用new运算符同样可以对数组的空间进行分配,动态分配数组的语法如下:数据类型*指针变量=new数据类型[长度];这里长度可以是常量,也可以是变量,分配后,得到的指针变量指向数组的开始地址,在访问数组元素时,可以将指针变量名当作数组名来使用。不再使用new分配的数组后,需要使用delete运算符进行释放:delete[]指针变量;这里delete的后面需要有中括号,表示对数组空间的释放。C++程序设计及项目实践34例9.14动态分配数组的示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05intm,n;06cin>>m>>n;07//一维数组动态分配08int*pa=newint[n];09for(inti=0;i<n;i++)10{11pa[i]=3*i+1;12}13//二维数组动态分配14//分配所有行15int**pb=newint*[m];16for(intr=0;r<m;r++)17{18//分配某一行的所有列19pb[r]=newint[n];20for(intc=0;c<n;C++)21{22pb[r][c]=(r+1)*(c+1);23}24}25cout<<"firstarray:"<<endl;26for(inti=0;i<n;i++)27{28cout<<pa[i]<<'\t';29}30cout<<endl<<"secondarray:"<<endl;31for(intr=0;r<m;r++)32{33for(intc=0;c<n;C++)34{35cout<<pb[r][c]<<'\t';36}37cout<<endl;38}39//一维数组释放40delete[]pa;41//二维数组所有列释放42for(intr=0;r<m;r++)43{44delete[]pb[r];45}46//二维数组所有行释放47delete[]pb;48return0;49}C++程序设计及项目实践35C++程序设计及项目实践369.4.2 结构体类型内存动态分配结构体指针变量同样可以赋予某个结构体变量的内存地址,也可以动态分配一个内存空间。动态分配的语法形式如下:结构体类型名*指针变量=new结构体类型名;在拥有结构体指针后,可以将*结构体变量看成普通的结构体变量,并使用点”.”成员访问符对结构体中的成员进行读写,也可以直接用结构体指针配合箭头”->”成员访问符对结构体指针中的成员进行读写。在结构体指针使用完成后,使用new动态分配的结构体指针,也需要使用delete进行释放。C++程序设计及项目实践37例9.15结构体指针分配示例程序代码:01#include<iostream>02#include<cstring>03usingnamespacestd;0405intmain(){06structStudent07{08intnum;09charname[10];10};11Studentstu{1000,"zhang"};12Student*pstu1,*pstu2;13pstu1=&stu;14pstu2=newStudent;15pstu2->num=2000;16strcpy(pstu2->name,"li");17cout<<"Student1:"<<endl18<<pstu1->num<<'\t'19<<pstu1->name<<endl;20cout<<"Student2:"<<endl21<<pstu2->num<<'\t'22<<pstu2->name<<endl;23deletepstu2;24return0;25}C++程序设计及项目实践389.5 单向链表
当程序需要使用大量相同数据类型数据时,可以使用数组来管理,数组在内存中的连续存储,这对于数据的检索相关的操作非常方便,但是对于需要更新数据的场景就非常不遍,比如若要在数组中间增加或者删除一项时,为了保证数组存储的连续性,需要对数据项进行移动,这就增加了系统的时空消耗,而且,当增加的数据项过多超过数组长度时,可能会导致数组不能增加。
数组中存在的缺点,使用链表可以克服,链表从逻辑上看也是数据在内存中线性排列,不过在内存中不一定是连续存放,所以它可以灵活地支持动态增加或删除数据项。
下面是一个包含四个节点的单向链表的图示,单向指链表节点中包含的指针只指向一个方向,即从头到尾。数据中间节点(第二个节点)下一节点地址数据头节点(第一个节点)下一节点地址数据尾节点(最后一个节点)NULL数据中间节点(第三个节点)下一节点地址C++程序设计及项目实践39例9.16一个简单链表的示例程序代码:01#include<iostream>02#include<cstring>03usingnamespacestd;0405structStudent06{07intid;08charname[20];09Student*pNext;10};1112intmain(){13Student*pHead,*pSecond,*pThird,*pTail;14//单独建立各个节点15pHead=newStudent;16pHead->id=1000;17strcpy(pHead->name,"zhao");18pSecond=newStudent;19pSecond->id=2000;20strcpy(pSecond->name,"qian");21pThird=newStudent;22pThird->id=3000;23strcpy(pThird->name,"sun");24pTail=newStudent;25pTail->id=4000;26strcpy(pTail->name,"li");27//将各个节点串联起来成为一个链表28pHead->pNext=pSecond;29pSecond->pNext=pThird;30pThird->pNext=pTail;31pTail->pNext=NULL;32//利用循环语句显示链表33cout<<"showlist:"<<endl;34Student*pTemp=pHead;35while(pTemp!=NULL)36{37cout<<pTemp->id<<'\t'<<pTemp->name<<endl;38pTemp=pTemp->pNext;39}40//删除第二个节点,不破坏链表41pHead->pNext=pThird;42deletepSecond;43//利用循环语句显示删除了第二个节点之后的链表44cout<<"deletethesecondnode,showlist:"<<endl;45pTemp=pHead;46while(pTemp!=NULL)47{48cout<<pTemp->id<<'\t'<<pTemp->name<<endl;49pTemp=pTemp->pNext;50}51deletepHead;52deletepThird;53deletepTail;54return0;55}C++程序设计及项目实践40数据pSecond下一节点地址数据pHead下一节点地址数据pTailNULL数据PThird下一节点地址C++程序设计及项目实践419.6 引用引用(reference)是一个现有变量的别名,一旦对已有的变量建立一个引用,则可以认为原始变量名和引用名是等价的,均代表同样的内存空间。C++程序设计及项目实践429.6.1 引用声明及使用声明一个引用必须同时对其进行初始化,一旦声明引用之后,不能再将该引用名修改为其他变量的引用。声明应用的语法形式如下:数据类型&引用名=变量名;&表示引用,注意和取址运算符区分开,这里是放在赋值表达式的左侧。使用该表达式声明之后,引用名和变量名都代表了同样的内存空间。C++程序设计及项目实践43例9.17引用示例程序代码:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06floatf=4.5f;07doubled=6.7;08int&ri=i;09float&rf=f;10double&rd=d;11i++;12cout<<ri<<endl;13rf*=rf;14cout<<f<<endl;15rd=rd*d;16cout<<rd<<endl;17return0;18}C++程序设计及项目实践449.6.2 引用作为函数参数引用可以作为函数的参数,此时在函数内部对形式参数的任何操作,就相当于对主调函数中实际参数的操作,这种特性往往比先前使用指针传递参数来改变实参更加方便。C++程序设计及项目实践45例引用作为函数参数交换值程序代码:01#include<iostream>02usingnamespacestd;0304structStudent05{06intid;07charname[20];08};09voidmyswap(Student&stu1,Student&stu2)10{11Studentstu=stu1;12stu1=stu2;13stu2=stu;14}15voidmyswap(int&x,int&y)16{17inttemp=x;18x=y;19y=temp;20}2122intmain(){23inti=3,j=4;24myswap(i,j);25cout<<i<<'\t'<<j<<endl;26Studentstu1={1,"zhang"},stu2={2,"li"};27myswap(stu1,stu2);28cout<<"student1:"<<stu1.id<<'\t'<<<<endl;29cout<<"student2:"<<stu2.id<<'\t'<<<<endl;30return0;31}C++程序设计及项目实践463变量i别名x4变量j别名y(1)4变量i别名x3变量j别名y(2)1,”zhang”变量stu1别名stu12,”li”变量stu2别名stu2(1)2,”li”
变量stu1别名stu11,”zhang”
变量stu2别名stu2(2)C++程序设计及项目实践479.6.3 引用作为函数返回值引用同样可以作为函数的返回值,由于函数内部的局部变量会随着函数的退出而被释放,所以如果要能返回某个变量的引用,则该变量需要为全局变量、局部静态变量、使用new分配的变量等。C++程序设计及项目实践48例9.19引用作为函数返回值示例程序代码:01#include<iostream>02usingnamespacestd;0304intgi=0;05int&getRef(intx,inty)06{07gi=x+y;08returngi;09}1011int&getRef(intx)12{13staticinti=x*x;14returni;15}1617intmain(){18int&ret1=getRef(3);19int&ret2=getRef(3,4);20cout<<ret1<<'\t'<<ret2<<endl;21return0;22}C++程序设计及项目实践499.7 const对指针及引用的写保护指针和引用均提供了某种间接访问内存空间的机制,尤其在作为函数参数传递时,可以只传递实参地址,而无需拷贝完整的实参,这种参数传递的方式可以减少时间和空间消耗,但由于在函数内部可以通过修改形参来改变实参,这在某些时候可能会造成意想不到的后果,因此需要对函数参数进行保护,const就提供了保护指针和引用的方法。C++程序设计及项目实践509.7.1 保护指针及指针指向值const对指针可以保护三个方法:保护指针存储地址、保护指针指向空间、同时保护指针存储地址和指针指向空间。(1) const保护指针存储地址:数据类型*constp,这种方式下,p为初始化常量,不能对p进行修改而改变初始值。(2) const保护指针指向空间:数据类型const*p或者const数据类型*p,这种方式下*p为保护空间,不能对*p进行修改。(3) const保护指针存储地址和指向空间:const数据类型*constp或者数据类型const*constp,这种方式下p及*p均不能再次被修改。C++程序设计及项目实践51例9.20const指针保护示例程序代码:01#include<iostream>02usingnamespacestd;0304voidshowOne(constint*p)05{06//不能执行*p=x;07cout<<"constint*p"<<endl;08cout<<*p<<endl;09}1011voidshowTwo(int*constp)12{13//不能执行p=&x;14cout<<"int*constp"<<endl;15cout<<*p<<endl;16}1718voidshowThree(constint*constp)19{20//不能执行p=&x或*p=x;21cout<<"constint*constp"<<endl;22cout<<*p<<endl;23}2425intmain(){26inti=3;27intj=4;28intk=5;29intconst*pi=&i;30int*constpj=&j;31intconst*constpk=&k;32pi=&j;//不能执行*pi=j;33*pj=i;//不能执行pj=&i;34//不能执行pk=&i或*pk=i;35cout<<*pi<<endl;36cout<<*pj<<endl;37cout<<*pk<<endl;38showOne(&i);39showTwo(&j);40showThree(&k);41return0;42}C++程序设计及项目实践52C++程序设计及项目实践539.7.2 保护引用const可以对引用传递的函数参数进行保护,限制在函数内部对形式参数的修改。形式为:const数据类型&引用名,这种方式下,引用会成为常量,不能对引用重新赋值。C++程序设计及项目实践54例9.21const引用保护示例程序代码:01#include<iostream>02usingnamespacestd;0304structStudent05{06intid;07charname[20];08};0910voidshow(constStudent&stu)11{12//不能修改stu.id或者的值13cout<<stu.id<<endl14<<<<endl;15}1617intmain(){18Studentstu{1000,"zhang"};19show(stu);20return0;21}C++程序设计及项目实践559.8应用C++程序设计及项目实践56例9.22字符串截取,截取某个位置开始的若干长度的字符串。思路:设计函数boolstrmid(char*dest,char*src,intpos,intlen),其中src为需要获取的源字符串,dest为最后获得的目标字符串,pos为源字符串中的截取字符的起始位置,len为获取的字符个数。C++程序设计及项目实践57例9.22字符串截取,截取某个位置开始的若干长度的字符串。程序代码:01#include<iostream>02usingnamespacestd;0304boolstrmid(char*dest,char*src,intpos,intlen)05{06boolisin=false;07inti=0;08for(i=0;src[i]!='\0';i++)09{10if(i==pos)11{12isin=true;13break;14}15}16if(!isin)17{18returnfalse;19}20intn=0;21for(i=pos;src[i]!='\0'&&n<len;i++,n++)22{23dest[n]=src[i];24}25dest[n]='\0';26returntrue;27}28intmain(){29constintLEN=80;30charfirst[LEN]="IloveChineseandMathmatics";31charsecond[LEN];32if(strmid(second,first,7,30))33{34cout<<second<<endl;35}36else37{38cout<<"noresult"<<endl;39}40return0;41}C++程序设计及项目实践58C++程序设计及项目实践59例9.23利用函数指针实现通用的排序功能,支持任意基础数据类型(整型、浮点型、字符型)数组的增序或降序排列。思路:设计一个模板函数boolselectSort(T*a,intn,bool(*pfun)(T,T)),其中第三个参数为函数指针,并另外编写两个模板函数booldescend(Tx,Ty),boolascend(Tx,Ty),在函数调用时,将这两个函数名传递进第一个函数,从而可以控制升序或降序。C++程序设计及项目实践60例9.23利用函数指针实现通用的排序功能,支持任意基础数据类型(整型、浮点型、字符型)数组的增序或降序排列。程序代码:01#include<iostream>02usingnamespacestd;0304template<typenameT>05booldescend(Tx,Ty)06{07returnx>y;08}0910template<typenameT>11boolascend(Tx,Ty)12{13returnx<y;14}1516template<typenameT>17boolselectSort(T*a,intn,bool(*pfun)(T,T))18{19for(inti=0;i<n-1;i++)20{21for(intj=i+1;j<n;j++)22{23if(!pfun(a[i],a[j]))24{25Tt=a[i];26a[i]=a[j];27a[j]=t;28}29}30}31returntrue;32}3334intmain(){35inta[8]={1,2,3,4,5,6,7,8};36selectSort(a,8,descend);37for(intx:a)38{39cout<<x<<'\t';40}41cout<<endl;42doubleb[7]={7.6,6.5,5.4,4.3,3.2,2.1,1.0};43selectSort(b,7,ascend);44for(doubley:b)45{46cout<<y<<'\t';47}48cout<<endl;49return0;50}C++程序设计及项目实践61例9.24使用链表管理学生信息思路:管理学生信息主要包括对学生信息的增加、删除、修改、查询、浏览操作,可以利用链表来管理所有学生信息,并使用各个函数在链表上进行操作。C++程序设计及项目实践62例9.24使用链表管理学生信息程序代码:01#include<iostream>02#include<cstring>03usingnamespacestd;04 05structStudent06{07intid;08charname[20];09Student*pNext;10};1112//增加一个节点13Student*addNode(Student*head)14{15Student*p=newStudent;16cout<<"id:";17cin>>p->id;18cout<<"name:";19cin>>p->name;20p->pNext=head;21returnp;22}2324//显示链表25voidshowList(Student*head)26{27Student*p=head;28while(p!=NULL)29{30cout<<p->id<<'\t'<<p->name<<endl;31p=p->pNext;32}33}3435//删除链表36voidclearList(Student*head)37{38Student*p=head,*pt;39while(p!=NULL)40{41pt=p;42p=p->pNext;43deletept;44}45}4647//查询节点48boolfindNode(Student*head)49{50cout<<"findid:";51intn;52cin>>n;53Student*p=head;54while(p!=NULL)55{56if(p->id==n)57{58cout<<"ok:"<<p->name<<endl;59returntrue;60}61p=p->pNext;62}63cout<<"no"<<endl;64returnfalse;65}6667//修改节点68boolmodifyNode(Student*head)69{70cout<<"modifyid:";71intn;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025湿地承包转让合同样本
- 2025简约租房合同模板
- 2025个人住宅买卖协议合同
- 2025授权贷款借款合同协议
- 2025橙子购销合同样本
- 2025中国移动各省招聘笔试参考题库附带答案详解
- 2025版专利技术许可合同样本:专利权的授权与使用
- 2025版急性心肌梗死常见症状及护理经验
- 2025版血栓形成常见症状及护理原则
- 消防救援安全训练
- 2025年食品安全管理员考试题库(附答案)
- 2025浙江金华市交通投资集团有限公司招聘笔试笔试历年参考题库附带答案详解
- 2025中国大唐集团新能源股份有限公司本部应届毕业生招聘笔试历年常考点试题专练附带答案详解2套试卷
- 2025四川广安投资集团有限公司第一次招聘工作人员18人笔试考试参考试题及答案解析
- 2025四川南充市嘉陵城市发展集团有限公司招聘10人笔试历年参考题库附带答案详解
- 2025年广西信息职业技术学院辅导员招聘考试笔试模拟试题及答案解析推
- 道路运输企业安全生产责任清单
- 1年级上册口算题2000道大全 A4打印版
- 浙江省初中名校发展共同体2024-2025学年第一学期七年级数学期中试卷(含答案)
- 2025年护理副高级职称题库及答案
- 微生物检验课件
评论
0/150
提交评论