• 1.31 MB
  • 2022-04-22 11:15:56 发布

C++程序设计 第2版 (吴乃陵 况迎辉 著) 高等教育出版社 课后答案

  • 198页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'课后答案网:www.hackshp.cn课后答案网您最真诚的朋友www.hackshp.cn网团队竭诚为学生服务,免费提供各门课后答案,不用积分,甚至不用注册,旨在为广大学生提供自主学习的平台!课后答案网:www.hackshp.cn视频教程网:www.efanjy.comPPT课件网:www.ppthouse.com课后答案网www.hackshp.cn若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn当前位置:学习资源下载>课后习题答案第一章C++CC++++基础知识习题1.11.1判断下列标识符的合法性。sinbook5arry_nameExample2.1main$1class_cppa3x*ymyname答:合法的:sinbook_namemainclass_cppa3非法的:5arryExample2.1$1x*ymyname1.21.2假定有下列变量:inta=3,b=5,c=0;floatx=2.5,y=8.2,z=1.4;charch1=’a’,ch2=’5’,ch3=’0’,ch4;求下列表达式的值,以及运算后表达式所涉及的各变量的值。x+(int)y%ax=z*b++,b=b*x,b++ch4=ch3-ch2+ch1int(y/z)+(int)y/(int)z!(a>b)&&c&&(x*=y)&&b++ch3||(b+=a*c)||c++z=(a<<2)/(b>>1)答:x+(int)y%a值为:4.5x=z*b++,b=b*x,b++值为:42,x为7,b为43ch4=ch3-ch2+ch1值为:’\’int(y/z)+(int)y/(int)z值为:13!(a>b)&&c&&(x*=y)&&b++值为:0,b为5注:只要出现一个false右边的不再做。ch3||(b+=a*c)||c++值为:1,c为0注:只要出现一个true,右边不再做。z=(a<<2)/(b>>1)值为:61.31.3判断下列哪些是常量,哪些是变量。"China"const课后答案网intn=10;intm=5;"a"charch="a"intarray[5]={1,2,3,4,5};chars[]="Hello";答:"China"文字常量www.hackshp.cnconstintn=10;常变量intm=5;变量"a"文字常量charch="a"变量intarray[5]={1,2,3,4,5};变量chars[]="Hello";变量1.41.4将下列算式或叙述用C++表达式描述。(1)(2)(x+y)/((x-y)*ay)(3)位于原点为圆心,a,b为半径的圆环中的点坐标。(4)。若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn(5)并且字符ch不为""。答:pi/2+sqrt(asin(x)*asin(x)+c*c)(x+y)/((x-y)*pow(a,y))((x*x+y*y)>=a*a)&&((x*x+y*y)<=b*b)(a!=b)&&(a!=c)&&(b!=c)(k<=20)&&(ch!="")1.61.6设有语句:inta,b;floatx,y;charch1,ch2,ch3;cin>>a>>b>>x>>y>>ch1;ch2=cin.get();cin>>ch3;若从键盘输入:321.87abc执行后各变量取值如何?注意abc三字符两两间有空格。答:a是3,b是2,x是1.8,y是7,ch1是’a’,ch2是空格,ch3是’b’。1.71.7设有语句:inta,b,c,d;cin>>oct>>a>>b>>hex>>c>>dec>>d;若从键盘输入:23232323执行后各变量的值用十进制表示各是多少?答:a:19,b:19课后答案网,c:35,d:231.81.8对于习题1.7,若执行:cout<课后习题答案第二章基本控制结构程序设计习题一.基本概念与基础知识自测题2.12.1程序阅读题2.1.1设有说明:inta=3,b=100;下面的循环语句执行(1)次,执行后a、b的值分别为(2)、(3)。while(b/a>5){if(b-a>25)a++;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnelseb/=a;}解答:本题检查学生整除的概念。跟踪:abb/a循环次数b-a310033197410025296510020395……………15100613851610061484171005停(1)14(2)17(3)1002.1.2设有说明:intx,y,n,k;下面程序段的功能是备选答案中的(1),当n=10,x=10打印结果是(2)。cin>>x>>n;k=0;do{x/=2;k++;}while(k=10)break;if(m%2==0){m+=5;continue;}m-=3;}解答:注意continue语句的使用初值m=0k=1第1次循环后m=5k=2第2次循环后m=2k=3第3次循环后m=7k=4第4次循环后m=4k=5第5次循环后m=9k=6第6次循环后课后答案网m=6k=7第7次循环后m=11k=8第8次循环www.hackshp.cnm=11结束k=8,k++未做(1)11(2)8二.编程与综合练习题2.2有一个函数:编写程序,输入x,输出y。解:#includeusingnamespacestd;intmain(){doublex,y;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncout<<"输入x=";cin>>x;if(x<1)y=x;elseif(x<10)y=2*x-1;elsey=3*x-11;cout<<"y="<usingnamespacestd;intmain(){intmark,result;//mark是百分制成绩,result是5分制cout<<"请输入百分制成绩:"<>mark;if(mark<0){cout<<"缺考!"<usingnamespacestd;intmain(){doubleincome,tax=0;intk;cout<<"请输入个人月收入:"<>income;if(income<=1200){cout<<"免征个人所得税"<20000){k=income/20000;switch课后答案网(k){default:tax+=(income-100000)*0.45;income=100000;case4:tax+=(income-80000)*0.40;income=80000;case3:tax+=(income-60000)*0.35;income=60000;www.hackshp.cncase2:tax+=(income-40000)*0.30;income=40000;case1:tax+=(income-20000)*0.25;income=20000;}}if(income>5000){tax+=(income-5000)*0.20;income=5000;}if(income>2000){tax+=(income-2000)*0.15;income=2000;}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnif(income>500){tax+=(income-500)*0.10;income=500;}tax+=income*0.05;cout<<"应征所得税:"<usingnamespacestd;intmain(){inti,j;for(i=1;i<=4;i++){for(j=4-i;j>0;j--)cout<<"";//三角形每行前部的空格for(j=1;j<=2*i-1;j++)cout<<"*";cout<usingnamespacestd;intmain(){charin;inti,j;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cndo{cout<<"输入一个字母:";cin>>in;if((in>=97)&&(in<=122))in-=32;//小写改大写}while((in<65)||(in>90));intline=in-"A";for(i=0;i<=line;i++){//上三角for(j=line-i;j>0;j--)cout<<"";//前方空格for(j=1;j<=2*i+1;j++)cout<<""<0;i--){//下三角(少一行)for(j=0;j<=line-i;j++)cout<<"";for(j=1;j<=2*i-1;j++)cout<<""<#includeusingnamespacestd;intmain(){intn,i,jch=1;doubleresult=0;//result是结果cout<<"请输入正整数课后答案网n:"<>n;if(n<1){cout<<"输入错误!www.hackshp.cn"<usingnamespacestd;constintday=10;intmain(){inti,x=1;//最后一天只有一个for(i=1;i#includeusingnamespacestd;intmain(){intstem[256],sum=0,pnum=0,nnum=0,i=0;cout<<"从键盘输入一组非0整数,以输入0标志结束:"<>stem[i];while(stem[i]!=0){sum+=stem[i];//求和if(stem[i]>0)pnum++;//正数数量elsennum++;//负数数量i++;cin>>stem[i];课后答案网}if(!i)cout<<"0个数"<usingnamespacestd;intmain(){若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cninti;for(i=1;i<=500;i++)if((i%3==2)&&(i%5==3)&&(i%7==2))cout<usingnamespacestd;intmain(){inti,a,sum_yz;//sum_yz是a的因子和for(a=1;a<1000;a++){sum_yz=0;for(i=1;iusingnamespacestd;intmain(){课后答案网inti,j,k,count=0;for(i=0;i<=10;i++)//i是10元张数,j是5元张数,k是1元张数for(j=0;j<=20;j++){www.hackshp.cnk=100-10*i-5*j;if(k>=0){cout<#includeusingnamespacestd;constdoublee=1e-5;intmain(){doublex,a,sum;inti=3;cout<<"请输入正切值:"<>x;a=x;sum=x;do{a*=x*x*(-1);sum+=a/i;i+=2;}while(fabs(a/i)>e);cout<<"arctg("<课后答案网#includeusingnamespacestd;constdoublee=1e-5;www.hackshp.cnintmain(){doublex0,x1;intn=0;cout<<"输入初始近似值:"<>x1;do{x0=x1;x1=(x0*x0-10*(x0*sin(x0)+cos(x0)))/(2*x0-10*sin(x0));//x0是上次算出的结果,x1用作保存新算出的结果n++;}while((fabs(x1-x0)>e)&&(n<=1e5));if(n>1e5)若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncout<<"超出迭代1e5次n";elsecout<<"方程x*x+10*cos(x)=0的一个根为:"<usingnamespacestd;intmain(){charst1[5]={"A","B","C","D","E"},st2[5]={"J","K","L","M","N"};inti=0,j,k,l,m,n;for(j=0;j<5;j++){//0号位if(j==0)continue;//A选手不与选手J比赛,即st1[0]不与st2[0]比赛for(k=0;k<5;k++){//1号位if(k==j)continue;//剔除乙队占据0号位的选手for(l=0;l<5;l++){//2号位if(l==j||l==k)continue;//剔除乙队占据0、1号位的选手for(m=0;m<5;m++){//3号位if(m==j||m==k||m==l)continue;//剔除乙队占据0、1、2号位的选手if(m==3)continue;//st1[3]不与st2[3]比赛,即D不与M比赛课后答案网for(n=0;n<5;n++){//4号位if(n==j||n==k||n==l||n==m)continue;//剔除乙队占据0、1、2、3号位的选手www.hackshp.cnif(n==3)continue;//st1[4]不与st2[3]比赛,即E不与M比赛cout<#includeusingnamespacestd;intmain(){enumcandidate{feipiao,zhang,wang,li,zhao}cand;intvote[5]={0},i,k=0,n;cin>>n;while(n!=-1){k++;if(n>=1&&n<=4)vote[n]++;elsevote[0]++;cin>>n;}for(i=0;i<5;i++){cand=(candidate)i;switch(cand){casefeipiao:cout<k/2)cout<<"当选"<k/2)cout<<"www.hackshp.cn当选"<k/2)cout<<"当选"<k/2)cout<<"当选"<>i>>j>>k>>l;等,并输出最后关闭文件:file.close();#include#include#includeusingnamespacestd;constintm=20;intmain(){intfib0=0,fib1=1,fib2,i,j,k,l,n;charch;ofstreamofile("myfile2_17.txt");ofile<>ch;www.hackshp.cnif(ch=="y"||ch=="Y"){ifstreamifile("myfile2_17.txt");while(1){ifile>>i>>j>>k>>l>>n;//由文件读入if(ifile.eof()!=0)break;cout<#include#include#includeusingnamespacestd;constintn=100;intmain(){inta[n],i,j;charch,b[256];ofstreamofile;ifstreamifile;for(i=0;i>ch;if(ch=="y"||ch=="Y"){ifile.open("myfile2_18.txt");i=0;while(ifile.get(b[i])){//不可用>>,它不能读白字符,if(b[i]=="n")break;i++;}b[i]="";cout<>i;//由文件读入cout<#includeusingnamespacestd;intmain(){charch;intnline=0,nword=0,nch=0;intisword=0;ifstreamifile("ep2_19.cpp");cout<<"读入ep2_19.cpp"<课后习题答案第三章函数习题一.基本概念与基础知识自测题3.13.1填空题3.1.1被定义为形参的是在函数中起(1)作用的变量,形参只能用(2)表示。实参的作用是(3),实参可以用(4)、(5)、(6)表示。答案:(1)自变量(2)变量名(3)将实际参数的值传递给形参(4)具有值的变量(5)常量(6)表达式3.1.2局部域包括(1)、(2)和(3)。使用局部变量的意义在于(4)。答案:(1)块域(2)函数域(3)函数原型域(4)局部变量具有局部作用域使得程序在不同块中可以使用同名变量3.1.3静态局部变量存储在(1)区,在(2)时候建立,生存期为(3),如定义时未显式初始化,则其初值为(课后答案网4)。答案:(1)全局数据区(2)编译www.hackshp.cn(3)全局生存期(4)全03.1.4局部变量存储在(1)区,在(2)时候建立,生存期为(3),如定义时未显式初始化,则其初值为(4)。答案:(1)栈(2)在函数或块开始执行时(3)函数或块的执行期(4)随机值3.1.5编译预处理的作用是(1),预处理指令的标志是(2)。多文件系统中,程序由(3)若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn来管理,用户自定义头文件中通常定义一些(4)。答案:(1)将源程序文件进行处理,生成一个中间文件,编译系统对此中间文件进行编译并生成目标代码(2)#(3)工程文件(4)用户构造的数据类型(如枚举类型),外部变量,外部函数、常量和内联函数等具有一定通用性或常用的量3.1.6设有函数说明如下:intf(intx,inty){returnx%y+1;}假定a=10,b=4,c=5,下列语句的执行结果分别是(1)和(2)。(1)cout<usingnamespacestd;inta,b;voidf(intj){staticinti=a;//注意静态局部变量intm,n;m=i+j;i++;j++;n=i*j;a++;cout<<"i="<usingnamespacestd;floatsqr(floata){returna*a;}floatp(floatx,intn){cout<<"in-process:"<<"x="<usingnamespacestd;charcapitalize(charch){if(ch>="a"&&ch<="z")returnch-"a"+"A";elsereturnch;}intmain(){inti=0;charcp[30];cout<<"请输入包含小写字母的句子:"<usingnamespacestd;MaxCommonDevisor(intn,intm){inti;for(i=n;i>=1;i--)if(n%i==0&&m%i==0)break;returni;}MinCommonMultiple(intn,intm){若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cninti;for(i=n;i<=n*m;i++)if(i%n==0&&i%m==0)break;returni;}intmain(){inti,j;cout<<"请输入两个整数:"<>i>>j;cout<<"最大公约数:"<usingnamespacestd;digit(intnum,intk){ints[10]={0,0,0,0,0,0,0,0,0,0};inti=0;do{//先把整数转换为数字串s[i]=num%10;num/=10;i++;}while(num>0);if(k<=i)return课后答案网s[k-1];//题目中位数的下标从1开始,而数组下标从0开始elsereturn0;}intmain(){www.hackshp.cncout<<"digit(4647,3)="<usingnamespacestd;factors(intnum,intk){//缺省返回值为整型intcount=0;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnwhile(num%k==0){count++;num/=k;}returncount;}intmain(){cout<<"factors(1875,5)="<#includeusingnamespacestd;boolprime(intm){if(m==1||m==0)returnfalse;if(m==2)returntrue;intk=(int)sqrt(m);for(inti=2;i<=k;i++)//穷举法if(m%i==0)break;if(i>k)returntrue;elsereturnfalse;}课后答案网intmain(){for(intn=4;n<=50;n+=2){for(inti=2;i<=n/2;i++)www.hackshp.cnif(prime(i)&&prime(n-i))cout<usingnamespacestd;voidPrintDiagram(intm){inti;cout<<"|"<usingnamespacestd;Acm(intm,intn){if(m==0)returnn+1;if(n==0)return课后答案网Acm(m-1,1);returnAcm(m-1,Acm(m,n-1));}intmain(){www.hackshp.cncout<<"Acm(2,1)="<usingnamespacestd;doubleP(intn,doublex){若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnif(n==0)return1;if(n==1)returnx;return((2*n-1)*x*P(n-1,x)-(n-1)*P(n-2,x))/n;}intmain(){cout<<"P(4,1.5)="<usingnamespacestd;inlinemax(inta,intb,intc){if(a>b&&a>c)returna;if(b>a&&b>c)returnb;returnc;}intmain(){cout<="0"&&ch<="9"来判断。#includeusingnamespacestd;课后答案网inlineboolIfDigitChar(charch){if(ch>="0"&&ch<="9")return1;elsereturn0;www.hackshp.cn}intmain(){charch;cout<<"请输入一个字符(输入“!”停止)"<>ch;while(ch!="!"){if(IfDigitChar(ch))cout<>ch;}return0;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}3.13设计两个重载函数,分别求两个整数相除的余数和两个实数相除的余数。两个实数求余定义为实数四舍五入取整后相除的余数。解:实数四舍五入取整,正数是+0.5取整,负数是-0.5取整。#include#includeusingnamespacestd;mod(intn,intm){returnn%m;}round(doublex){//四舍五入函数if(x>=0)returnint(x+0.5);elsereturnint(x-0.5);}mod(doublex,doubley){returnround(x)%round(y);}intmain(){cout<<"mod(8,3)="<usingnamespacestd;#include"area.h"intmain(){doublea,b,r;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncout<<"inputradius:"<>r;cout<<"inputsidelength:"<>a>>b;cout<<"area("<0){for(i=0;i0){p2(w-1);for(i=0;i0){for(i=0;i0){若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnfor(i=0;i课后习题答案第四章类与对象习题一.基本概念与基础知识自测题课后答案网4.14.1填空题5.1.1引入类定义的关键字是(1)。类的成员函数通常指定为(2),类的数据成员通常指定为(3)www.hackshp.cn。指定为(4)的类成员可以在类对象所在域中的任何位置访问它们。通常用类的(5)成员表示类的属性,用类的(6)成员表示类的操作。答案:(1)class(2)公有的public(3)私有的private(4)公有的public(5)数据(6)函数4.1.2类的访问限定符包括(1)、(2)和(3)。私有数据通常由(4)函数来访问(读和写)。这些函数统称为(5)。答案:(1)public(公有的)若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn(2)private(私有的)(3)protected(保护的)(4)公有的成员函数(5)类的接口4.1.3通常在逻辑上,同一类的每个对象都有(1)代码区,用以存储成员函数。而在物理上通常只有(2)代码区。只有在(3)定义,并(4)的函数和加了关键字(5)的函数例外。答案:(1)独立的(2)共用的(3)在类说明中(4)不包括循环等复杂结构(5)inline4.1.4C++中支持三种域:(1)、(2)、(3)。函数域被包括在(4)中,全局域被包括在(5)中。using指示符以关键字using开头,后面是关键字(6),最后是(7)。这样表示以后在该名字空间中所有成员都(8)。如不使用using指示符则在使用时要加::::,称为(9)运算符。答案:(1)局部域(localscope)(2)名字空间域(namespacescope)(3)类域(classscope)(4)局部域(5)名字空间域(6)namespace(7)名字空间名(8)可以直接被使用(9)域4.1.5引用通常用作函数的(1)和(2)。对数组只能引用(3)不能引用(4)。答案:课后答案网(1)参数(2)返回值(3)数组元素www.hackshp.cn(4)数组名本身4.1.6构造函数的任务是(1)。构造函数无(2)。类中可以有(3)个构造函数,它们由(4)区分。如果类说明中没有给出构造函数,则C++编译器会(5)。拷贝构造函数的参数是(6),当程序没有给出复制构造函数时,系统会自动提供(7)支持,这样的复制构造函数中每个类成员(8)。答案:(1)初始化数据成员(2)函数返回类型说明(3)多(4)不同的参数表(5)自动给出一个默认的构造函数(6)同一类对象的引用若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn(7)默认的的复制构造函,称为默认的按成员语义支持。(8)被依次复制4.1.7一个类有(1)个析构函数。(2)时,系统会自动调用析构函数。答案:(1)一(2)对象注销时4.1.8运算符重载时,其函数名由(1)构成。成员函数重载双目运算符时,左操作数是(2),右操作数是(3)。答案:(1)关键字operator和该运算符(2)对象(3)该函数的参数4.1.9面向过程的程序设计中程序模型描述为(1),面向对象程序设计的程序模型可描述为(2)。答案:(1)“程序=算法+数据结构”。其数据与数据处理是分离的。(2)程序=(对象+对象+……+对象)+消息;对象=(算法+数据结构)。面向对象设计将数据和对数据的操作方法放在一起,形成一个相对独立的整体——对象(Object),并通过简单的接口与外部联系。对象之间通过消息(Message)进行通讯。4.2简答题4.2.1简单解释什么是面向对象程序设计的封装性。答:对象是一个封装体,在其中封装了该对象所具有的属性和操作。对象作为独立的基本单元,实现了将数据和数据处理相结合的思想。此外,封装特性还体现在可以限制对象中数据和操作的访问权限,从而将属性“隐藏”在对象内部,对外只呈现一定的外部特性和功能。封装性增加了对象的独立性,C++通过建立数据类型——类,来支持封装和数据隐藏。一个定义完好的类一旦建立,就可看成完全的封装体,作为一个整体单元使用,用户不需要知道这个类是如何工作的,而只需要知道如何使用就行。另一方面,封装增加了数据的可靠性,保护类中的数据不被类以外的程序随意使用。这两个优点十分有利于程序的调试和维护。课后答案网4.2.2C++编译器怎样对标识符进行解析?答:编译器对标识符的解析分两步,第一步查找在声明中用到的标识符,特别是函数成员声www.hackshp.cn明中用到的参数类型,第二步是函数成员体内的标识符。4.2.3为什么说类与对象的概念是客观世界的反映?答:客观世界的事物都具有某些属性和行为(或操作),具有相同属性和行为的事物可以归属于一类,用分类的方法可以提高认识事物的效率。C++中定义的类则是通过抽象的方法将某一类事物共有的静态特征(属性)和动态特征(行为)概括出来并加以描述,而对象是类的具体实现,所以说类与对象的概念是客观世界的反映。4.2.4什么叫类域?为什么说类域是抽象的?答:类域是类体所包括的范围。每个类定义都引入了一个独立的类域,在类域中说明的标识符仅在该类的类域中有效。由于类只是一个说明,看上去有数据,有函数,有类型定义,但是它并非实体,不分配内存,当然也不能运行。所以说类域是抽象的。若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn4.2.5引用作为函数参数时为什么能实现两个实参之间的数据交换?为什么对应实参不能为引用?为什么返回值为引用的函数可以作为左值?答:引用变量是其关联变量的别名,二者在内存中占据同一个存储单元。在一个以引用作为参数的函数中,交换两个参数的值,实际上就是交换两个实参的值。如果函数的参数是引用,调用时需要取得实参的地址,而实参如果已经是一个地址,再进行引用将产生错误,故对应实参不能为引用。函数返回引用实际是指明(返回)了相应的关联变量,所以声明返回值为引用的函数实际上是将关联变量作为左值参与运算。4.2.6什么是缺省的构造函数?缺省的构造函数最多可以有多少个?答:如果在类定义中不显式地定义构造函数,C++编译器会自动产生一个缺省的构造函数,不过该函数不做具体的初始化工作。只要构造函数是无参的或者只要各参数均有缺省值的,C++编译器都认为是缺省的构造函数。缺省的构造函数只能有一个。4.2.7拷贝构造函数用于哪三个方面?答:(1)用类的一个对象去初始化该类的另一个对象时使用。(2)当函数的形参是类的对象,调用函数时,进行形参与实参结合时使用。(3)当函数的返回值是类对象,函数执行结束返回调用者时使用。4.2.8写出含有对象成员的类的构造函数的格式,并做简单说明。答:C++中对含对象成员的类对象的构造函数有固定的格式:类名::构造函数名(参数总表):对象成员1(参数名表1),对象成员2(参数名表2),……对象成员n(参数名表n){……}冒号后用逗号隔开的是要初始化的对象成员,附在后面的参数名表1,…,参数名表n依次为调用相应对象成员所属的构造函数时的实参表。这些表中的参数通常来自冒号前的参数总表,但没有类型名。课后答案网4.2.9所有类对象未重载的赋值运算符“=”是怎样工作的?为什么它可以进行连续赋值?答:对所有的类对象,未重载的赋值运算符“=”称作缺省的按成员拷贝赋值操作符,同类对象之间可以用“=”直接拷贝。因为缺省的赋值操作返回一个对象的引用,所以它可以进www.hackshp.cn行连续赋值。4.2.10为什么在友元函数的函数体内访问对象成员时,必须用对象名加运算符“.”再加对象成员名?答:友元函数不是类的成员函数,在函数体中访问对象的成员,必须用对象名加运算符“.”加对象成员名。这一点和一般函数一样。4.2.11重载复数运算符+时,采用下面友元函数声明:friendComplexoperator+(Complex&c1,Complex&c2);为什么不能用于“实数+复数”?怎样改进才能适用?为什么?答:使用引用类型变量作为运算符重载函数的参数,身为左值的实数类型实参不能被转换为复数,编译时无法通过。添加const说明,使实数到复数的转换隐式地在一份拷贝上进行,若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn则可以实现“实数+复数”运算。修改后的说明为:friendComplexoperator+(constComplex&c1,constComplex&c2);4.2.12类的静态数据成员与函数中的静态成员有何异同?答:类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中,为该类所有对象公用。函数中的静态变量也位于公用内存中,不随函数调用而重新分配,所以总是保留上次进入并执行该函数后留下的信息。4.2.13C++中结构、联合与类三者间有何异同?答:在C++中结构(structure)与类几乎是完全一样的类型,差别仅仅在于缺省情况下结构的成员为公有的。联合(union)是C++的导出数据类型,在语法与功能上类似于结构,二者的区别是:结构变量的各成员同时被分配了各自独立的内存区,而联合变量的各个成员的存储开始地址都相同,所以在任一时刻联合变量只能存储一个成员。4.2.14对象的第一特征是封装,那么由对象组成的面向对象的程序怎样建立各对象之间的有效联系?面向对象程序的组织与面向过程有什么不同?答:因为对象的操作主要用来响应外来消息并为其他对象提供服务,所以面向对象的程序利用消息传递机制来建立各对象之间的有效联系,协调各对象的运行。一个对象可以向其他对象发送消息以请求服务,也可以响应其他对象传来的消息,完成自身固有的某些操作,从而服务于其他对象。面向过程的程序是模块化的,模块的组织具有分层结构特点,层与层之间是调用关系。面向对象程序是由一个个封装的对象组成,而对象是由紧密结合在一起的算法和数据结构组成。对象之间是相互请求和相互协作的关系。4.2.15简叙Windows下应用程序的运行方式。答:Windows系统支持多个应用程序同时执行,在界面形式上,它支持多个窗口同时活动。它的运行机制是“消息传递和事件驱动(messagebasedandeventdriven)”。Windows系统使用事件驱动的编程模式。所谓事件的含义非常广泛。输入设备的动作,如敲打键盘、按鼠标等会产生一课后答案网系列的事件(注意不是一个事件)。操作系统所作的一举一动也被当作某种类型的事件,应用程序也会产生各种事件。事件用来标识发生的某件事情。Windows系统对于应用程序环境中发生的每一个事件都会以对应的某种消息的形式标识,并放入相应的Windowswww.hackshp.cn建立的消息队列中,然后由对应的应用程序或窗口函数去处理。窗口函数处理是分层的,前面处理不了的送到后面,最后处理不了剩下的全由缺省的窗口函数处理。4.2.16类的成员函数在什么情况下应该定义为私有的?这样做的目的是什么?答:除接口函数和创建本类对象的构造函数和撤消该对象的析构函数外。其余成员函数应该定义为私有的,这是开发类时故意对外隐蔽起来的操作,而这些往往是最复杂最关键的部分。类中故意的隐藏也为以后的升级扩展留下了余地,只要接口不变,内部再变,也不必修改原来的程序,就象MFC(微软基础类)升级后,由MFC底层类所编的程序完全不必修改,自动升级。二.编程与综合练习题4.3构造一个日期时间类(Timedate),数据成员包括年、月、日和时、分、秒,函数成员若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn包括设置日期时间和输出时间,其中年、月请用枚举类型,并完成测试。(包括用成员函数和用普通函数)解:本题要求仅是定义类的练习,并非实用的提供日期时间的程序。实用的日期时间程序见附录二的日期时间函数。#include#includeusingnamespacestd;enumYR{Y2000,Y2001,Y2002,Y2003,Y2004,Y2005};//enumMT{Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec};classTimedate{private:YRyear;MTmonth;intdate;inthh;intmm;intss;public:Timedate(){year=Y2000;month=Jan;date=1;hh=0;mm=0;ss=0;}Timedate(YRa,MTb,intc){year=a;month=b;date=c;hh=12;mm=30;ss=0;}voidgetdate(YR&,MT&,int&);//使用引用一次取得3个数值voidgettime(int&,int&,int&);voidputdate(YR,MT,int);voidputtime(课后答案网int,int,int);voidlist();};voidTimedate::getdate(YR&y,MT&m,www.hackshp.cnint&d){y=year;m=month;d=date;}voidTimedate::gettime(int&a,int&b,int&c){a=hh;b=mm;c=ss;}voidTimedate::putdate(YRa,MTb,intc){year=a;month=b;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cndate=c;}voidTimedate::puttime(inta,intb,intc){hh=a;mm=b;ss=c;}voidTimedate::list(){//成员函数,直接访问私有的数据成员cout<<"year/month/date:";switch(year){caseY2000:cout<<"2000";break;caseY2001:cout<<"2001";break;caseY2002:cout<<"2002";break;caseY2003:cout<<"2003";break;caseY2004:cout<<"2004";break;caseY2005:cout<<"2005";break;}switch(month){caseJan:cout<<"/"<<"Jan";break;caseFeb:cout<<"/"<<"Feb";break;caseMar:cout<<"/"<<"Mar";break;caseApr:cout<<"/"<<"Apr";break;caseMay:cout<<"/"<<"May";break;caseJun:cout<<"/"<<"Jun";break;caseJul:cout<<"/"<<"Jul";break;caseAug:cout<<"/"<<"Aug";break;caseSep:cout<<"/"<<"Sep";break;caseOct:cout<<"/"<<"Oct";break;caseNov:cout<<"/"<<"Nov";课后答案网break;caseDec:cout<<"/"<<"Dec";break;}cout<<"/"<#includeusingnamespacestd;classRectangle{doubleleft,top;doubleright,bottom;public:Rectangle(doublel=0,doublet=0,doubler=0,doubleb=0);~Rectangle(){};//析构函数,在此函数体为空voidAssign(doublel,doublet,doubler,doubleb);doublegetLeft(){returnleft;}//以下四个函数皆为内联成员函数doublegetRight(){returnright;}doublegetTop(){returntop;}doublegetBottom(){returnbottom;}voidShow();doubleArea();doublePerimeter();};//构造函数,带缺省参数,缺省值为全0,在声明中指定Rectangle::Rectangle(doublel,doublet,doubler,doubleb){left=l;top=t;right=r;bottom=b;}voidRectangle::Assign(doublel,doublet,doubler,doubleb){//赋值left=l;top=t;right=r;bottom=b;}voidRectangle::Show(){//成员函数直接使用私有的数据成员cout<<"left-toppointis("<#includeusingnamespacestd;classCircle{doubler,Area,Circumference;public:Circle(doublea=0);Circle(Circle&);voidSetR(doubleR);doubleGetR(){returnr;}doubleGetAreaCircle(){returnArea;}doubleGetCircumference(){returnCircumference;}};Circle::Circle(doublea){r=a;Area=r*r*3.14159265;Circumference=2*r*3.14159265;课后答案网}Circle::Circle(Circle&cl){r=cl.r;www.hackshp.cnArea=cl.Area;Circumference=cl.Circumference;}voidCircle::SetR(doubleR){r=R;Area=r*r*3.14159265;Circumference=2*r*3.14159265;}intmain(){Circlecl1(2),cl2,cl3=cl1;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncout<<"圆半径:"<#includeusingnamespacestd;enumTsex{mid,man,woman};classPerson{charIdPerson[19];//身份证号,18位数字charName[20];//姓名TsexSex;//性别intBirthday;//生日,格式1986年8月18日写作19860818charHomeAddress[50];//家庭地址public:Person(char*,char*,Tsex,int,char*);Person(Person&);Person();~Person();voidPrintPersonInfo();voidinputPerson();课后答案网//其他接口函数};Person::Person(char*id,char*name,Tsexsex,www.hackshp.cnintbirthday,char*homeadd){cout<<"构造Person"<>ch;if(ch=="m")Sex=man;elseSex=woman;cout<<"请输入生日,格式1986年8月18日写作19860818:"<>Birthday;cin.get();//吸收回车符,否则地址输不进去cout<<"请输入地址:"<#includeusingnamespacestd;classRectangle{doubleleft,top;doubleright,bottom;public:Rectangle(doublel=0,doublet=0,doubler=0,doubleb=0);~Rectangle(){};//析构函数,在此函数体为空voidAssign(doublel,doublet,doubler,doubleb);doublegetLeft(){returnleft;}//以下四个函数皆为内联成员函数doublegetRight(){returnright;}doublegetTop(){returntop;}doublegetBottom(){returnbottom;}voidShow();friendvoidshowprint(Rectangle);doubleArea();doublePerimeter();};课后答案网//构造函数,带缺省参数,缺省值为全0,在声明中指定Rectangle::Rectangle(doublel,doublet,doubler,doubleb){left=l;top=t;www.hackshp.cnright=r;bottom=b;}voidRectangle::Assign(doublel,doublet,doubler,doubleb){//赋值left=l;top=t;right=r;bottom=b;}doubleRectangle::Area(){returnfabs((right-left)*(top-bottom));}doubleRectangle::Perimeter(){return2*(fabs(right-left)+fabs(top-bottom));}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnvoidRectangle::Show(){//成员函数cout<<"left-toppointis("<usingnamespacestd;classcomplex{private:doublereal;//实部doubleimag;//虚部public:complex(doubler=0.0,doublei=0.0);//构造函数voidprint();//显示复数complexoperator+(complexc);//重载复数"+"complexoperator-(complexc);//重载复数"-"complexoperator*(complexc);//重载复数"*"若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncomplexoperator/(complexc);//重载复数"/"complexoperator+=(complexc);//重载复数"+="complexoperator-=(complexc);//重载复数"-="complexoperator*=(complexc);//重载复数"*="complexoperator/=(complexc);//重载复数"/="complexoperator++();//重载复数前缀"++"complexoperator++(int);//重载复数后缀"++"};complex::complex(doubler,doublei){real=r;imag=i;}complexcomplex::operator+(complexc){//重载复数"+"complextemp;temp.real=real+c.real;temp.imag=imag+c.imag;returntemp;//返回局部变量,函数声明不可为引用,这时返回了局部变量的地址}complexcomplex::operator-(complexc){//重载复数"-"complextemp;temp.real=real-c.real;temp.imag=imag-c.imag;returntemp;}complexcomplex::operator*(complexc){//重载复数"*"complextemp;temp.real=real*c.real-imag*c.imag;temp.imag=real*c.imag+imag*c.real;returntemp;课后答案网}complexcomplex::operator/(complexc){//重载复数"/"complextemp;www.hackshp.cndoubled;d=c.real*c.real+c.imag*c.imag;temp.real=(real*c.real+imag*c.imag)/d;temp.imag=(c.real*imag-real*c.imag)/d;returntemp;}complexcomplex::operator+=(complexc){//重载复数"+="complextemp;temp.real=real+c.real;temp.imag=imag+c.imag;real=temp.real;imag=temp.imag;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnreturntemp;}complexcomplex::operator-=(complexc){//重载复数"-="complextemp;temp.real=real-c.real;temp.imag=imag-c.imag;real=temp.real;imag=temp.imag;returntemp;}complexcomplex::operator*=(complexc){//重载复数"*="complextemp;temp.real=real*c.real-imag*c.imag;temp.imag=real*c.imag+imag*c.real;real=temp.real;imag=temp.imag;returntemp;}complexcomplex::operator/=(complexc){//重载复数"/="complextemp;doubled;d=c.real*c.real+c.imag*c.imag;temp.real=(real*c.real+imag*c.imag)/d;temp.imag=(c.real*imag-real*c.imag)/d;real=temp.real;imag=temp.imag;returntemp;}complexcomplex::operator课后答案网++(){//重载复数前缀"++"complextemp;temp.real=++real;temp.imag=++imag;www.hackshp.cnreturntemp;}complexcomplex::operator++(int){//重载复数后缀"++"complextemp(real,imag);real++;imag++;returntemp;}voidcomplex::print(){//显示复数cout<=0)cout<<"+";cout<classcomplex{若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnprivate:doublereal;//实部doubleimag;//虚部public:complex(doubler=0.0,doublei=0.0);//构造函数voidprint();//显示复数friendcomplexoperator+(constcomplex&,constcomplex&);//重载复数"+"friendcomplexoperator-(constcomplex&,constcomplex&);//重载复数"-"friendcomplexoperator*(constcomplex&,constcomplex&);//重载复数"*"friendcomplexoperator/(constcomplex&,constcomplex&);//重载复数"/"friendcomplex&operator+=(complex&,constcomplex&);//重载复数"+="friendcomplex&operator-=(complex&,constcomplex&);//重载复数"-="friendcomplex&operator*=(complex&,constcomplex&);//重载复数"*="friendcomplex&operator/=(complex&,constcomplex&);//重载复数"/="friendcomplexoperator++(complex&);//重载复数前缀"++"friendcomplexoperator++(complex&,int);//重载复数后缀"++"};complex::complex(doubler,doublei){real=r;imag=i;}complexoperator+(constcomplex&c1,constcomplex&c2){//重载复数"+"complextemp;temp.real=c1.real+c2.real;temp.imag=c1.imag+c2.imag;returntemp;//返回局部变量,函数声明不可为引用,这时返回了局部变量的地址}complexoperator-(constcomplex&c1,constcomplex&c2){//重载复数"-"complextemp;课后答案网temp.real=c1.real-c2.real;temp.imag=c1.imag-c2.imag;returntemp;www.hackshp.cn}complexoperator*(constcomplex&c1,constcomplex&c2){//重载复数"*"complextemp;temp.real=c1.real*c2.real-c1.imag*c2.imag;temp.imag=c1.real*c2.imag+c1.imag*c2.real;returntemp;}complexoperator/(constcomplex&c1,constcomplex&c2){//重载复数"/"complextemp;doubled;d=(c2.real*c2.real+c2.imag*c2.imag);temp.real=(c1.real*c2.real+c1.imag*c2.imag)/d;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cntemp.imag=(c2.real*c1.imag-c1.real*c2.imag)/d;returntemp;}complex&operator+=(complex&c1,constcomplex&c2){//重载复数"+="c1.real=c1.real+c2.real;c1.imag=c1.imag+c2.imag;returnc1;//返回由引用参数传递过来的变量,函数声明可为引用}complex&operator-=(complex&c1,constcomplex&c2){//重载复数"-="c1.real=c1.real-c2.real;c1.imag=c1.imag-c2.imag;returnc1;}complex&operator*=(complex&c1,constcomplex&c2){//重载复数"*="complextemp;temp.real=c1.real*c2.real-c1.imag*c2.imag;temp.imag=c1.real*c2.imag+c1.imag*c2.real;c1=temp;returnc1;}complex&operator/=(complex&c1,constcomplex&c2){//重载复数"/="complextemp;doubled;d=(c2.real*c2.real+c2.imag*c2.imag);temp.real=(c1.real*c2.real+c1.imag*c2.imag)/d;temp.imag=(c2.real*c1.imag-c1.real*c2.imag)/d;c1=temp;returnc1;}课后答案网complexoperator++(complex&c){//重载复数前缀"++"++c.real;++c.imag;www.hackshp.cnreturnc;}complexoperator++(complex&c,int){//重载复数后缀"++"complextemp(c.real,c.imag);c.real++;c.imag++;returntemp;}voidcomplex::print(){//显示复数cout<=0)cout<<"+";cout<ksi[0]=0x6f6d;s->ksi[1]=0x6e72;s->ksi[2]=0x6e69;s->ksi[3]=0x0067;cout<word<usingnamespacestd;unionchint{charword[10];课后答案网shortintksi[5];};www.hackshp.cnintmain(){//数字转换为字符串chintx,*s;s=&x;s->ksi[0]=0x6f63;s->ksi[1]=0x706d;s->ksi[2]=0x7475;s->ksi[3]=0x7265;s->ksi[4]=0x0021;cout<word<usingnamespacestd;classIntRMB{//人民币类private:intIYuan;intJiao;intFen;public:IntRMB(inty=0,intj=0,intf=0);//构造函数voidprint();//数据输出函数operatorfloat();//浮点数类型转换函数};IntRMB::IntRMB(inty,intj,intf){//构造函数IYuan=y;Jiao=j;Fen=f;}IntRMB::operatorfloat(){floattemp;课后答案网temp=float(IYuan+(Jiao/10.0)+(Fen/100.0));returntemp;}www.hackshp.cnvoidIntRMB::print(){cout<课后习题答案第五章数组与指针习题一、.基本概念与基础知识自测题5.15.1填充题5.1.1数组定义时有三个要素:数组名,数组元素的(1)和数组元素的(2)。按元素在数组中的位置进行访问,是通过(3)进行的,称为(4)或(5)访问。为了使数组声明中数组的大小修改更为方便,总是将(6)用于声明数组长度。答案:(1)类型(2)数量(3)下标运算符(4)下标(5)索引(6)常变量5.1.2C/C++中的多维数组用的是一个(1)的定义,即多维数组的基本定义是(2)构成的数组,三维数组的元素是(3)。答案:(1)嵌套(2)以数组作为元素(3)二维数组5.1.3计算机内存是一维编址的,多维数组在内存中的存储(1),C/C++多维在内存中的排列是(2)方式,即越(3)的下标变化(4)。设数组a有m行n列,每个元素占内存u个字节,则a[i][j]的首地址为(5)+(6)。答案:(1)必须要转化为一维方式,(2)按行方式(3)右(4)越快(5)a数组的首地址课后答案网(6)(i*n+j)*u5.1.4对于多维数组,(1)www.hackshp.cn的大小是确定的,所谓“不检查数组边界”只是不检查(2)的边界,而(3)的边界是在控制之中的,所以多维数组名作为函数的参数只可以(4)缺省。答案:(1)较低各维的(2)最高维(第一维)(3)较低各维(4)最高维5.1.5指针变量保存了另一变量的(1)值,不可以任意给指针变量赋一个地址值,只能赋给它(2)和(3)的地址。使用变量名来访问变量,是按(4)来直接存取变量称为(5)方式;而借助指针变量取得另一变量的地址,访问该变量称为(6)方式。答案:(1)地址(2)NULL若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn(3)已经分配了内存的变量的地址(4)按变量的地址(5)直接访问(6)间接访问5.1.6固定指向一个对象的指针,称为(1),即(2),定义时const放在(3)。而指向“常量”的指针称为(4),指针本身可以指向别的对象,但(5),定义时const放在(6)。答案:(1)指针常量(2)指针本身是常量(3)const放在类型说明之后,变量名之前(4)常量指针(5)不能通过该指针修改对象(6)const放在类型说明之前5.1.7数组名在表达式中被自动转换为指向(1)的指针常量,数组名是地址,但数组名中放的地址是(2),所以数组名(3)。这样数组名可以由(4)来代替,C++这样做使用时十分方便,但丢失了数组的另一要素(5),数组名是指向数组(6)的指针,而不是指向数组(7)的。编译器按数组定义的大小分配内存,但运行时对(8)不加检测,这会带来无法预知的严重错误。答案:(1)数组第一个元素(2)不可改变的(3)称指针常量(4)指针(5)数组元素的数量(6)元素(7)整体(8)对数组的边界不加检测5.1.8有一个三维数组:课后答案网intz3d[2][3][4];给出指向三维数组第www.hackshp.cni行第j列第k页元素的指针的三种表达方式(1),(2),(3)。再给出这些元素的三种表达方式(4),(5),(6)。答案:(1)z3d[i][j]+k或&z3d[i][j][k](2)*(z3d[i]+j)+k(3)*(*(z3d+i)+j)+k(4)z3d[i][j][k]或*(z3d[i][j]+k)(5)*(*(z3d[i]+j)+k)(6)*(*(*(z3d+i)+j)+k)5.25.2简答题5.2.1物理上,C++是怎样访问数组元素的?请对访问方法作简单介绍。答:物理上,C++语言的下标运算符[]是以指针作为操作数的,a[i]被编译系统解释为*(a+i),即表示为a所指(固定不可变)元素向后第i个元素。无论我们是以下标方式或指针方式存取数组元素时,系统都是转换为指针方法实现。这样做对多维数组尤其方便。若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn5.2.2什么是回溯算法?答:回溯法是对枚举法的一种改进。回溯法的基本思想是,通过对问题的分析找出解决问题的线索,先在一个局部上找出满足问题条件的局部的解,然后逐步由局部解向整个问题的解的方向试探,若试探成功就得到问题的解,试探失败逐步向后退,改变局部解再向前试探。回溯法能避免枚举法的许多不必要的搜索,使问题比较快地得到解决。5.2.3用数组名作为函数的参数时,可否加上数组的长度?如果需要加则怎样加?为什么?答:被调函数中作为形式参数的一维数组不需要说明长度,即使说明了大小也不起作用,因为C++只传递数组首地址,而对数组边界不加检查。5.2.4需要编写一个对多维数组通用的算法(即各维的大小未定),怎样才能把实参多维数组的信息全部传递到函数中去?答:最佳方法是用函数模板,多维数组用模板类型参数传递,各维的大小作为参数传递。也可以用一维数组加各维的大小都作为参数传递。5.2.5解释运算符“*”和“&”的作用,运算符“.”和“->”的作用。答:在应用指针变量时,“*”是间接引用(dereference)运算符,作用于一个指针类型的变量,访问该指针所指向的内存数据。因结果是内存中可寻址的数据。“&”是取地址运算符,作用于内存中一个可寻址的数据(如:变量,对象和数组元素等等),操作的结果是获得该数据的地址。运算符“.”和“->”是成员访问运算符(MemberAccessOprator)。在对象或结构外部去访问公有的数据成员或函数成员时,是在对象名后加“.”(点操作符),再加成员函数名或函数名就可以了。但是这些成员必须是公有的成员,只有公有成员才能在对象的外面对它进行访问。当用指向对象和结构变量的指针访问其公有成员时,则只要在指针变量名后加“->”(箭头操作符),再加公有成员名就可以了。5.2.6什么是this指针?简述它的作用。答:当我们在对象的外部访问该对象的公有成员时,必须指明是哪一个对象。但是当我们用课后答案网对象的成员函数来访问本对象的成员时,在成员函数中只要给出成员名就可以实现对该对象成员的访问。但同一个类创建的多个对象共用同一份成员函数的拷贝。既然是同一份拷贝www.hackshp.cn,那么成员函数又怎么知道是取哪一个对象的成员数据呢?其实每一个对象有一个隐藏的thisthithiss指针,它始终指向该对象,并将该指针作为一个参数自动传递给该成员函数。这就是说,成员操作符总是要使用的,只不过在对象内是隐式的,即在对象内省略了this指针。5.2.7指针变量与整型量的加减运算代表什么意义?答:指针变量与整型量的加减表示移动指针,以指向当前目标前面或后面的若干个位置的目标。指针与整型量i的加减等于指针值(地址)与i*sizeof(目标类型)积的加减,得出新的地址。5.2.8设a为数组名,那么a++是否合法?为什么?答:非法。因为a是指针常量。5.2.9指针作为函数的参数时,它传递的是什么?实参要用什么?而使用引用时实参要用什么?何时只能用指针而不能用引用?若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn答:是地址,是指针所指向的变量或对象的内存首地址,在物理上讲我们传的是指针的值,与传其它变量是没有差异的,函数获得的是另一个变量的地址,在逻辑上讲我们是把另一个变量的地址传过去了,可以看作传地址。实参要用变量或对象的地址。而使用引用时实参要用变量或对象本身。实参为数组时,只能用指针而不能用引用,因为数组的引用不存在。5.2.10指针作为函数的返回值时,应该注意什么?答:指针指向的数据的生命期必须不仅仅在函数域中,函数消亡后,数据仍然存在。如果返回的指针,它所指的变量或对象已消亡,则该返回值无意义,这一点必须十分小心。总之直接使用指针不管是作为参数还是返回值,都要注意安全性。5.2.11设有语句char*ps=”It’sabook.”;是否建立了一个字符串,并把”it’sabook.”作为其初值?随后又有语句:*ps=”It’sacar”;这又代表什么?是否正确。答:没有建立字符串,只是让ps指向一个放在代码区中的特殊字符串,而该字符串所在内存是不可写的。后一条语句要求把字符串赋给不可写的字符串空间是错的。二、编程与综合练习题5.3打印杨辉三角形(10行)。使用二维数组并利用每个系数等于其肩上两系数之和。解:好的算法无特例,二维数组共用11列,第1列全0,方便计算#includeusingnamespacestd;intmain(){inta[10][11]={0,1},i,j;//初始化时写好第1行,其余各行全0for(i=1;i<10;i++)//为了全部算法无特例,共用11列,第1列全0,方便计算for(j=1;j<=i+1;j++)a[i][j]=a[i-1][j-1]+a[i-1][j];for(i=0;i<10;i++){for(j=1;j<=i+1;j++)cout<#includeusingnamespacestd;voidinverse(int[],int[],int,int);//注意数组最高维可缺省,例5.5因初学未省voidmulti(int[],int[],int[],int,int,int);voidoutput(int[],int,int);intmain(){intmiddle[6*3],result[6*4];//注意写作6*3等可清楚看出矩阵的行列若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnintmatrix1[3*6]={8,10,12,23,1,3,5,7,9,2,4,6,34,45,56,2,4,6};intmatrix2[3*4]={3,2,1,0,-1,-2,9,8,7,6,5,4};output(matrix1,3,6);inverse(matrix1,middle,3,6);output(middle,6,3);output(matrix2,3,4);multi(middle,matrix2,result,6,3,4);output(result,6,4);return0;}voidinverse(intmatrix1_1[],intmiddle_1[],inta,intb){inti,j;for(i=0;iusingnamespacestd;intatoi(chars[]){inttemp=0,f=1,i=0;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnwhile(s[i]!=""&&s[i]!="-"&&(s[i]<"0"||s[i]>"9"))i++;//去除串前部无效字符if(s[i]=="-"){//读负号f=-1;i++;}if(s[i]<"0"||s[i]>"9")cout<<"error!"<="0"&&s[i]<="9"){//转换数字串temp=temp*10+s[i]-48;i++;}returnf*temp;}intmain(){charnum[20];cin.getline(num,19);cout<usingnamespacestd;intmain(){若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnint*ip,ival=100;double*dp,dval=99.9;char*cp,cval="A";ip=&ival;dp=&dval;cp=&cval;cout<<*ip<<"t"<<&*ip<<"t"<usingnamespacestd;char*strcat1(char*s,constchar*ct){char*st=s;while(*s)s++;//*s作为条件,等效*s!=0while(*s++=*ct++);returnst;}intstrlen1(constchar*s){inti=0;while(*s++)i++;returni;}char*reverse(char*s){chartemp,*temp1=s,*temp2=s;while(*temp2)temp2++;temp2--;//指针移回串尾while(temp2-temp1>0){//注意此处,从串两头的指针同时向中间移动,重合或交错时停止temp=*temp1;*temp1=*temp2;*temp2=temp;temp1++;temp2--;}returns;}char*strchr(constchar课后答案网*cs,charc){while(*cs!=c&&*cs)cs++;if(*cs==0)cs=NULL;www.hackshp.cn//未找到返回NALLreturn(char*)cs;}char*strstr(constchar*cs1,constchar*cs2){char*temp;char*temp1=(char*)cs2;while(*cs1){//只要主串还有字符未查,则继续while(*cs1!=*cs2&&*cs1)cs1++;//找到主串含有子串的第一个字符,或主串查完停止temp=(char*)cs1;temp1=(char*)cs2;if(*cs1){//核对子串其他字符while(*cs1++==*temp1++||*temp1);if(*temp1==0)returntemp;//找到子串返回若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}}returnNULL;//未找到返回NAL}intmain(){chara[40]="李明";charb[20]="是东南大学学生";charc[40]="SoutheastUniversity";char*cp;cout<usingnamespacestd;char*reverse(char*s){chartemp,*temp1=s,*temp2=s;while(*temp2)temp2++;temp2--;//指针移回串尾while(temp2-temp1>0){//注意此处,从串两头的指针同时向中间移动,重合或交错时停止temp=*temp1;*temp1=*temp2;*temp2=temp;temp1++;temp2--;}returns;}课后答案网char*itoa(intn,char*string){char*temp=string;www.hackshp.cnif(n<0){*temp++="-";n=-n;}do{//注意个位放在前了*temp++=n%10+48;}while(n=n/10);//显式的循环*temp="";if(*string=="-")temp=string+1;//有负号仅反转数字部分elsetemp=string;reverse(temp);//个位放到后面returnstring;}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnchar*itoa1(intn,char*string){if(n<0){*string++="-";n=-n;}if(n/10)string=itoa1(n/10,string);//隐式循环*string++=n%10+48;//第一次是数字最高位放串的最前面的字符(不含符号),注意指针移动在后*string="";returnstring;//注意返回的指针已后移一字符}char*itoa0(intn,char*string){itoa1(n,string);returnstring;}intmain(){intnum;charst[20];cin>>num;cout<<"输出数字串:"<>num;cout<<"输出数字串:"<中定义一个日期时间的结构:structtm{inttm_sec;//秒inttm_min;课后答案网//分inttm_hour;//时inttm_mday;//日www.hackshp.cninttm_mon;//月inttm_year;//年,实际放的是与1970年的差,如1990年为20inttm_wday;//星期inttm_yday;//一年中的第几天inttm_isdst;//是否夏时制};函数time_ttime(time_t*tp)是提取当前时间,time_t即长整型,代表从1970年1月1日00:00:00开始计算的秒数(格林尼治时间),放在首地址为tp的单元内。函数tm*localtime(consttime_t*tp)将tp地址单元中的时间转换为日期时间结构的当地时间;(函数tm*gmtime(consttime_t*tp)转换为日期时间结构的格林尼治时间;)函数char*asctime(tm*tb)将tb地址单元中的tm结构的日期时间转换为字符串(供显示),它有固有格式,如:SunSep1601:03:521973若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn利用以上资源,重新设计一个日期时间类(DataTime),要求定义对象时取当前时间进行初始化,显示时重取显示时刻的时间并显示出来。解:#include#includeusingnamespacestd;classdatatime{tm*timedata;longallsecond;char*tmp;public:datatime(){time(&allsecond);timedata=localtime(&allsecond);tmp=asctime(timedata);cout<>ch;课后答案网if(ch=="y"||ch=="Y")dt.gettime();return0;www.hackshp.cn}5.11完善自定义字符串类mystring,函数包括:构造函数、拷贝构造函数、析构函数,并重载运算符[],=(分别用mystring和C字符串拷贝),+(strcat),+=,<,>,==(strcmp)。解:此例既是对第4章的复习也是一个提高。拷贝构造函数的应用请参阅4.4.2节末尾两项说明,本例形参使用引用,仅在返回时调用了拷贝构造函数。运算符的重载请参阅4.5节。#includeusingnamespacestd;constintn=256;classmystring{charstr[n];//存放字符串的数组容器intmaxsize;//最大可用元素数,可防止数组出界,提高健壮性若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnintlast;//已用元素最大下标public:mystring(){last=0;maxsize=n;str[0]="";cout<<"缺省构造函数"<last)last=i;//下标运算符,可添加长度但不查边界returnstr[i];}mystringoperator=(mystring&);mystring&operator=(char*ms);//这里重载的=是把C风格字符串赋给mystringmystringoperator+(mystring&);mystringoperator+=(mystring&);booloperator<(mystring&);booloperator>(mystring&);booloperator==(mystring&);若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn};mystringmystring::operator=(mystring&ms){last=-1;do{last++;str[last]=ms.str[last];}while(last(mystring&ms){//重载>运算符inti=0,k;do{k=str[i]-ms.str[i];i++;}while(k==0&&i0)returntrue;if(i==ms.last&&i!=last)returntrue;returnfalse;}boolmystring::operator==(mystring&ms){inti=0,k;if(last!=ms.last)returnfalse;do{k=str[i]-ms.str[i];i++;}while(k==0&&ims2){ms1.show();cout<<"应排在"<usingnamespacestd;constintn=256;classmystring{charstr[n];//存放字符串的数组容器intmaxsize;//最大可用元素数,可防止数组出界,提高健壮性intlast;//已用元素最大下标public:mystring(){课后答案网last=-1;maxsize=n;www.hackshp.cnstr[0]="";cout<<"缺省构造函数"<last)last=i;//下标运算符,可添加长度但不查边界returnstr[i];}mystring&operator=(mystring&);mystring&operator=(char*ms);//这里重载的=是把C风格字符串赋给mystringmystringoperator+(mystring&);//这里返回不能用引用mystring&operator+=(mystring&);booloperator<(mystring&);booloperator课后答案网==(mystring&);};voidmystring::reverse(){www.hackshp.cninti=0,j=last-1;chartemp;while(j>i){//注意此处,从串两头同时向中间移动,重合或交错时停止temp=str[i];//头尾交换str[i]=str[j];str[j]=temp;i++;j--;}}intmystring::strchr(charc){inti;for(i=0;i!=last;i++)if(str[i]==c)returni;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnreturn-1;//未找到返回-1}intmystring::strstr(mystringstr1){inti=0,k=1;while(str[i]!=""){//只要主串还有字符未查,则继续while(str[i]!=str1[0]&&str[i]!="")i++;//找到主串含有子串的第一个字符,或主串查完停止if(str[i]!=""){//核对子串其他字符while(str[i+k]==str1.str[k]&&k课后习题答案课后答案网第六章模板与数据结构习题一、.基本概念与基础知识自测题6.16.1填充题www.hackshp.cn6.1.1模板是为了实现代码的(1),它把数据类型改为一个(2),称为(3)程序设计。模板包括(4)和(5)。答案:(1)重用(2)设计参数(3)参数化(parameterize)(4)函数模板(functiontemplate)(5)类模板(classtemplate)6.1.2调用函数模板时,可以显式指定模板参数类型,也可以隐式进行,称为(1),这是根据(2)来决定的。答案:(1)模板实参推演(templateargumentdeduction)(2)一组实际类型或(和)值若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn6.1.3顺序查找可以用于(1)线性表,而对半查找可以用于(2)线性表。答案:(1)无序的(所有)(2)有序的6.1.4最常见的排序方式有(1)、(2)和(3)。如果现有一个已排好序的线性表,在表尾添加了一个元素,采用(4)排序法使它重新成为有序的所需工作量最小。答案:(1)选择(2)插入(3)交换(4)交换(可利用原来的有序性)6.1.5给出以下指针的说明方式:指向一个4元素整型数组的指针为(1);指向一个返回整型数,参数为两个整型数的函数的指针(2);指向一个数组的指针,而该数组元素都是指向一个返回整型指针的无参函数(3)。答案:(1)int(*p)[4](2)int(*p)(int,int)(3)以指向6元素数组为例:int*(*)()(*p)[6]6.26.2简答题6.2.1需要编写一个对多维数组通用的算法(即各维的大小未定),怎样才能把实参多维数组的信息全部传递到函数中去?答:最佳方法是用函数模板,多维数组用模板类型参数传递,各维的大小作为参数传递。也可以用一维数组加各维的大小都作为参数传递。6.2.2什么叫函数模板?什么叫模板函数?什么叫类模板?什么叫模板类?答:不受数据类型限制的通用型的函数使代码的可重用性大大提高。把数据类型改为一个设计参数是一个可行的方案。这种程序设计类型称为参数化(Parameterize)程序设计。这样的软件模块由模板(Template)构造。包括函数模板和类模板。函数模板定义如下:课后答案网template<模板参数表>返回类型函数名(形式参数表){……;//函数体www.hackshp.cn}模板参数主要是模板类型参数。模板类型参数代表一种潜在的内置或用户定义的类型,由关键字typename或class后加一个标识符构成。函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,简化重载函数的设计。由调用函数模板(functrontemplate)而生成的函数,称为模板函数(templatefunction)。类模板定义如下:template<模板参数表>class类名{……;//类声明体};模板参数有两种:模板类型参数和模板非类型参数。模板类型参数(templatetypeparameter),它代表一种类型,由关键字typename或class后加一个标识符。模板非类型参数由一个普通的参数声明构成。模板非类型参数表示该参数名代表了一个潜在的常量。如数组类模板,可以有一个数组长度的非类型参数。若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn为通用的类模板定义中的模板类型参数指定了具体类型而生成的类称为模板类。6.2.1什么叫线性表?其基本操作包括哪些?其中插入一个元素的关键在哪儿?答:线性表是数据结构中的概念:每两个相邻元素之间都有直接前驱和直接后继的关系。这里除第一个元素外,其他元素有且仅有一个直接前驱,第一个元素没有前驱;除最后一个元素外,其他元素有且仅有一个直接后继,最后一个元素无后继。这样的特性称为线性关系。基本操作包括:计算表长度,寻找变量或对象x(其类型与表元素相同)在表中的位置(下标值),判断x是否在表中,删除x,将x插入列表中第i个位置,寻找x的后继,寻找x的前驱,判断表是否空,判断表是否满,取第i个元素的值等。当需要在顺序表的指定位置i插入一个数据x时,必须为它腾出这个位置,把从该位置开始向后的所有元素数据,后移一个位置,最后才插入。关键是后移时从最后一个元素开始。否则先移的数据会冲掉未移的数据。6.2.2采用索引查找有哪些优点?它需要被查找数据有序吗?答:索引,就象一本书的目录,找到标题,再看一下页号,立即可以翻到。索引查找不要求被查找数据有序,只要求索引有序。6.2.3简单叙述阅读理解复杂指针的方法。设Node为类,下面两个标识符fa和pa分别代表什么?Node*(*fa(int))();Node*(*(*pa)[])();答:理解和构造对象说明的方法是:先撇开标识符,按从右到左的顺序逐个解释每个说明符,如果有括号则改变解释的先后,先解释括号内再解释括号外。fa是有一个整型参数的函数,其返回值是指针,该指针是指向无参函数的指针,而该无参函数的返回值是指向Node类的指针。pa是指向数组的指针,该数组的元素均为函数指针,所指向的函数无参、返回值是指向Node类的指针。二、.编程与综合练习题6.3使用自定义字符串类,编写求数组元素中最大值的函数模板。解:函数模板有三种应用方式:1.类模板的成员函数,在模板类型参数中重载函数和运算符,直接访问私有数据成员,实课后答案网现通用算法。这是标准的面向对象的方法。2.函数模板处理模板类,以类模版为参数,用模板类型参数中重载的函数或运算符,实现www.hackshp.cn通用算法。但调用类模板的接口函数间接访问私有数据成员,也是常见的。3.函数模板处理普通数据,往往要用函数作为参数,实现通用算法。这是面向过程的方法。解:使用独立的函数模板,相对简单。#includeusingnamespacestd;constintn=256;classmystring{//为简单只保留用到的函数charstr[n];//存放字符串的数组容器intmaxsize;//最大可用元素数,可防止数组出界,提高健壮性intlast;//已用元素数public:mystring(){last=-1;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnmaxsize=n;str[0]="";cout<<"缺省构造函数"<Groapmax(Groap*r_array,intsize){//这里是一个独立的函数模板Groapmax_val=r_array[0];for(inti=1;i(ms,6)).show();return0;}6.4将自定义字符串类用于对半查找的函数模板。解1:为简化,使用独立的函数模板#includeusingnamespacestd;constintn=256;classmystring{//为简单只保留用到的函数charstr[n];//存放字符串的数组容器intmaxsize;//最大可用元素数,可防止数组出界,提高健壮性intlast;//已用元素数若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnpublic:mystring(){last=-1;maxsize=n;str[0]="";cout<<"缺省构造函数"<intBinarySearch(T*array,T&x,intsize){//独立的函数模板inthigh=size-1,low=0,mid;//size当前有序表元素数量while(low<=high){mid=(low+high)/2;if(xusingnamespacestd;constintn=256;classmystring{//为简单只保留用到的函数charstr[n];//存放字符串的数组容器intmaxsize;//最大可用元素数,可防止数组出界,提高健壮性intlast;//已用元素数public:mystring(){last=-1;maxsize=n;str[0]="";cout<<"缺省构造函数"<www.hackshp.cnclassOrderedlist{intmaxsize;intlast;Tslist[size];public:intgetlast(){returnlast;}Tgetslist(intk){returnslist[k];}voidputslist(Tt,intk){slist[k]=t;}Orderedlist(){last=-1;maxsize=size;}boolInsert(T&elem,inti);voidprint();intBinarySearch(T);//无关成员函数省略,缺省的=等不必定义};//再次指出分号不可少若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cntemplateboolOrderedlist::Insert(T&elem,inti){if(i<0||i>last+1||last==maxsize-1)returnfalse;else{last++;for(intj=last;j>i;j--)slist[j]=slist[j-1];slist[i]=elem;returntrue;}}templatevoidOrderedlist::print(){inti;for(i=0;i<=last;i++){slist[i].show();if(i%5==4)cout<intOrderedlist::BinarySearch(Tx){//成员函数模板inthigh=last,low=0,mid;//size当前有序表元素数量while(low<=high){mid=(low+high)/2;if(xordlist;mystringn[h];charsp[h][10]={"东南大学","复旦大学","交通大学","南京大学","清华大学","天津大学","同济大学","浙江大学"};for(i=0;i#includeusingnamespacestd;templateclassOrderedlist{intmaxsize;intlast;Tslist[size];public:Orderedlist(){last=-1;maxsize=size;}voidBubbleSort();boolInsert(T&elem,inti);voidprint();//无关成员函数省略,缺省的=等不必定义};//再次指出分号不可少templateboolOrderedlist::Insert(T&elem,inti){if(i<0||i>last+1||last==maxsize-1)returnfalse;else{last++;for(intj=last;j>i;j--)slist[j]=slist[j-1];slist[i]=elem;returntrue;}}课后答案网templatevoidOrderedlist::print(){inti;www.hackshp.cnfor(i=0;i<=last;i++){cout<voidOrderedlist::BubbleSort(){//降序boolnoswap;inti,j;Ttemp;for(i=last;i>0;i--){//从上往下冒泡,对比例6.8有何不同?noswap=true;//未交换标志为真若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnfor(j=0;jordlist;stringn[h];stringsp[h]={"南京大学","东南大学","交通大学","清华大学","天津大学","复旦大学","浙江大学","同济大学"};for(i=0;i#includeusingnamespacestd;templateclassOrderedlist{intmaxsize;intlast;Tslist[size];public:Orderedlist(){last=-1;maxsize=size;}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnvoidBubbleSort();boolInsert(T&elem,inti);voidprint();voidMerge(Orderedlist&,Orderedlist&);//无关成员函数省略,缺省的=等不必定义};//再次指出分号不可少templateboolOrderedlist::Insert(T&elem,inti){if(i<0||i>last+1||last==maxsize-1)returnfalse;else{for(intj=last;j>i;j--)slist[j]=slist[j-1];slist[i]=elem;last++;returntrue;}}templatevoidOrderedlist::print(){inti;for(i=0;i<=last;i++){cout<voidOrderedlist::BubbleSort(){//升序boolnoswap;inti,j;Ttemp;for(i=last;i>0;i--){课后答案网//从上往下冒泡,对比例6.8有何不同?noswap=true;//未交换标志为真for(j=0;jvoidOrderedlist::Merge(Orderedlist&ls1,Orderedlist&ls2){inti=0,j=0,k=0;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnwhile((i<=ls1.last)&&(j<=ls2.last)){if(ls1.slist[i]ordlist,ordlist1,ordlist2;stringn[h],m[h];charsp1[h][10]={"南京大学","东南大学","交通大学","清华大学","天津大学","复旦大学","浙江大学","同济大学"};for(i=0;i#includeusingnamespacestd;templateclassOrderedlist{intmaxsize;intlast;Tslist[size];voidShellinsert(constint);public:intgetlast(){return课后答案网last;}Tgetslist(intk){returnslist[k];}voidputslist(Tt,intk){slist[k]=t;}www.hackshp.cnOrderedlist(){last=-1;maxsize=size;}boolInsert(T&elem,inti);voidprint();voidShellsort();//无关成员函数省略,缺省的=等不必定义};//再次指出分号不可少templateboolOrderedlist::Insert(T&elem,inti){if(i<0||i>last+1||last==maxsize-1)returnfalse;else{for(intj=last;j>i;j--)slist[j]=slist[j-1];slist[i]=elem;last++;returntrue;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}}templatevoidOrderedlist::print(){inti;for(i=0;i<=last;i++){cout<voidOrderedlist::Shellsort(){//成员函数intgap=(last+1)/2;while(gap){Shellinsert(gap);//一趟排序gap/=2;}}templatevoidOrderedlist::Shellinsert(constintgap){inti,j;Ttemp;//注意每一趟排序包含若干子序列,其中第一个子序列第一个元素是0号,第二个元素是gap号,//插入排序认为单个元素是排好序的,所以从每个子序列的第二个元素开始插入排序。for(i=gap;i<=last;i++){//从第一个子序列开始直接插入排序,但不是完成一个子序列,//再做下一个子系列,而是先做每个子序列的第一步,再做每个子序列的第二步,等等,//穿插完成。直接插入排序总是从后逐个向前,找到第一个比待插元素大的,则插在前面。temp=slist[i];课后答案网//待插元素放temp中j=i;while(j>=gap&&tempordlist;stringn[h];charsp[h][10]={"南京大学","东南大学","交通大学","清华大学","天津大学","复旦大学",若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn"浙江大学","同济大学"};for(i=0;i#includeusingnamespacestd;templateclassOrderedlist{intmaxsize;intlast;Tslist[size];public:intgetlast(){returnlast;}Tgetslist(intk){returnslist[k];}voidputslist(Tt,intk){slist[k]=t;}Orderedlist(){last=-1;maxsize=size;}boolInsert(T&elem,inti);voidprint();//无关成员函数省略,缺省的=等不必定义};//再次指出分号不可少templateboolOrderedlist::Insert(T&elem,inti){if(i<0||i>last+1||last==maxsize-1)returnfalse;else{www.hackshp.cnfor(intj=last;j>i;j--)slist[j]=slist[j-1];slist[i]=elem;last++;returntrue;}}templatevoidOrderedlist::print(){inti;for(i=0;i<=last;i++){cout<voidShellsort(Orderedlist&list){//非成员函数,仅以表模板类为参数intgap=(list.getlast()+1)/2;while(gap){Shellinsert(list,gap);//一趟排序gap/=2;}}//intsize必须保留templatevoidShellinsert(Orderedlist&list,constintgap){inti,j;Ttemp;//注意每一趟排序包含若干子序列,其中第一个子序列第一个元素是0号,第二个元素是gap号,//插入排序认为单个元素是排好序的,所以从每个子序列的第二个元素开始插入排序。for(i=gap;i<=list.getlast();i++){//从第一个子序列开始直接插入排序,但不是完成一个//子序列,再做下一个子系列,而是先做每个子序列的第一步,再做每个子序列的第二步,//等等,穿插完成。直接插入排序总是从后逐个向前,找到第一个比待插元素大的,则插在前面。temp=list.getslist(i);//待插元素放temp中j=i;while(j>=gap&&tempordlist;stringn[h];charsp[h][10]={"南京大学","东南大学","交通大学","清华大学","天津大学","复旦大学","浙江大学","同济大学"};for(i=0;i课后习题答案第七章动态内存分配习题一、基本概念与基础知识自测题7.17.1填空题7.1.1C/C++定义了4个内存区间:(1)、(2)、(3)和(4)。答案:(1)代码区,存放程序代码;(2)全局变量与静态变量区,存放全局变量或对象(包括静态);(3)局部变量区即栈(stack)区,存放局部变量;(4)自由存储区(freestore),即动态存储区或堆(heap)区。7.1.2静态定义的变量和对象用标识符命名,称为(1);而动态建立的称为(2),动态建立对象的初始化是通过(3)实现(4)。答案:(1)命名对象(2)无名对象(3)初始化式(initializer)(4)显式初始化7.1.3在用new运算符建立一个三维数组15*30*10时,使用了(1)个下标运算符,对应的用delete运算符注销这个三维数组时使用了(2)个下标运算符。new返回的指针是指向(3)的指针。答案:(1)3个(2)1个课后答案网(3)30行10列的2位数组7.1.4当动态分配失败,系统采用(www.hackshp.cn1)来表示发生了异常。如果new返回的指针丢失,则所分配的自由存储区空间无法收回,称为(2)。这部分空间必须在(3)才能找回,这是因为无名对象的生命期(4)。答案:(1)返回一个空指针(NULL)(2)内存泄漏(3)重新启动计算机后(4)并不依赖于建立它的作用域7.1.5按语义的默认复制构造函数和默认复制赋值操作符实现的复制称为(1),假设类对象obj中有一个数据成员为指针,并为这个指针动态分配一个堆对象,如用obj1按成员语义拷贝了一个对象obj2,则obj2对应指针指向(2)。答案:(1)浅拷贝(2)同一个堆对象若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn7.1.6单链表的结点包含两个域:(1)和(2)。使用链表的最大的优点是(3),即使是动态数组也做不到这一点。答案:(1)数据域(2)指针域(3)用多少空间,开多少空间7.1.7进入单链表必须通过单链表的(1),如果它丢失则(2),内存也(3),在单链表中进行的查找只能是(4)。答案:(1)头指针(2)链表整个丢失(3)会发生泄漏(4)顺序查找7.1.8对链栈,链的生成必须是向(1)生成,最新压栈的元素(结点),放在(2)位置,弹出时从(3)删除结点。对链队,采用向(4)生成,新入队的结点放在链的(5),出队操作在(6)位置。答案:(1)向前(2)链表头的位置(3)链表头(4)向后(5)尾部(6)链表头7.1.9在计算机中进行表达式的计算,为解决优先级和运算的结合性,必须使用(1)和(2)。在中缀表达式中,每个双目运算符放在(3)。答案:(1)数栈(2)运算符栈(3)它的两个运算符之间课后答案网7.1.10为了能重复利用一个队空间,要求把队说明成一个逻辑上的(www.hackshp.cn1)。答案:(1)循环队列7.1.11二叉树的特点是:(1)和(2)。答案:(1)每个结点最多有两个孩子(2)子树有左右之分7.1.12二叉树的遍历是按(1)分类,所谓中序遍历是(2)。答案:(1)访问子树根节点次序(2)先遍历该子树根结点的左子树回来后,接着再访问根结点,最后遍历右子树7.1.13二叉排序树又称(1)或(2)。其左子树上的所有结点均小于根结点的数据值,而右子树上的所有结点均大于根结点的数据值时,采用(3)就可以得到一个(4)。答案:(1)二叉搜索树若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn(2)树表(3)中序遍历(4)升序序列7.27.2简答题7.2.1new运算符为一个变量或对象分配存储空间和为一个数组分配存储空间,使用方法上有什么不同?对应的delete运算符使用有什么不同?答:为一个变量或对象分配存储空间其使用的格式如下:指针变量名=new类型名(初始化式);对于数组进行动态分配和撤销的格式为:指针变量名=new类型名[下标表达式];后者多一个[下标表达式],同时不能进行初始化。对应的delete运算符使用分别为:delete指针名;delete[]指向该数组的指针变量名;后者多一个方括号,如果delete语句中少了方括号,因编译器认为该指针是指向数组第一个元素的指针,会产生回收不彻底的问题(只回收了第一个元素所占空间),加了方括号后就转化为指向数组的指针,回收整个数组。delete[]的方括号中不需要填数组元素数,系统自知。即使写了,编译器也忽略。7.2.2用delete删除p所指向的无名对象时,p指针也同时被删除了,对不对?为什么?答:不对。注意这时释放了p所指向的无名对象占用的内存空间,也就是撤销了该无名对象,称动态内存释放(dynamicmemorydeallocation),但指针p本身并没有撤销,它仍然存在,该指针所占内存空间并未释放。7.2.3为什么动态建立类对象数组时,类的定义一定要有缺省的构造函数?答:new后面类(class)类型也可以有参数。这些参数即构造函数的参数。但对创建数组,没有参数,只能调用缺省的构造函数。课后答案网7.2.4要实现深拷贝,自定义的拷贝构造函数应该怎样设计?答:如果类中有一个数据成员为指针,该类的一个对象中的这个指针www.hackshp.cnp,指向了动态分配的一个堆对象。深拷贝时要给新建立的对象独立分配一个堆对象。这时拷贝的构造函数应该设计为:先拷贝对象主体,再为新建对象的指针分配一个堆对象,最后用原对象的堆对象拷贝新对象的堆对象。即分三步完成。7.2.5在单链表模板中为什么要把List类说明成Node的友元类?答:为了直接访问结点的私有成员数据,以简化程序。7.2.6双向链表与单向链表相比,操作上有什么优点?答:双向链表可以很方便地找到表结点的前驱和后继。单链表只能找后继。如要找前驱,必须从表头开始搜索,并一般要用两个工作指针。7.2.7对比顺序栈与链栈各自的长处和短处。答:顺序栈可以随机访问其中的元素,而链栈只能顺序访问。顺序栈必须先开一定大小内存若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn空间,执行起来简单,速度快,但可能溢出。链栈内存空间随用随开,不会溢出,但执行复杂(不断地动态分配),速度慢。7.2.8写出二叉树的定义。答:二叉树是结点的一个有限集合,该集合或为空,或是由一个根结点及两棵分别称为左子树和右子树的(注意有左右之分)互不相交的二叉树组成,其中左右子树分别可以为空子树或均为空树。7.2.9什么是二叉树的遍历?答:所谓二叉树的遍历(binarytreetraversal),就是遵从某种次序,查巡二叉树的所有结点,每个结点都被访问一次,而且仅访问一次。所谓“访问”指对结点施行某些操作,但不破坏它原来的数据结构。二、编程与综合练习题7.3给单链表类模板增加两个成员函数:删除链表中所有数据域为指定值的结点和取出链表中第K个元素(从1开始计数)。解:这两个成员函数添在单链表类模板中(ep7_3.h)本例数据域用了标准类string,也可以使用整数型。//ep7_3.h#includeusingnamespacestd;//首先看结点组织,采用结点类,凡与结点数据和指针操作有关函数作为成员函数templateclassList;templateclassNode{Tinfo;//数据域Node*link;//指针域public:Node();//生成头结点的构造函数Node(constT&data);课后答案网//生成一般结点的构造函数voidInsertAfter(Node*P);//在当前结点后插入一个结点Node*RemoveAfter();www.hackshp.cn//删除当前结点的后继结点,返回该结点备用T&Getinfo();//增加取数据域函数friendclassList;//以List为友元类,List可直接访问Node的私有函数,与结构一样方便,但更安全};templateNode::Node(){link=NULL;}templateNode::Node(constT&data){info=data;link=NULL;}templatevoidNode::InsertAfter(Node*p){p->link=link;link=p;}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cntemplateNode*Node::RemoveAfter(){Node*tempP=link;if(link==NULL)tempP=NULL;//已在链尾,后面无结点elselink=tempP->link;returntempP;}templateT&Node::Getinfo(){returninfo;}//增加取数据域函数//再定义链表类,选择常用操作:包括建立有序链表、搜索遍历、插入、删除、取数据等templateclassList{Node*head,*tail;//链表头指针和尾指针public:List();//构造函数,生成头结点(空链表)~List();//析构函数voidMakeEmpty();//清空一个链表,只余表头结点Node*Find(Tdata);//搜索数据域与data相同的结点,返回该结点的地址intLength();//计算单链表长度voidPrintList();//打印链表的数据域voidInsertFront(Node*p);//可用来向前生成链表,在表头插入一个结点voidInsertRear(Node*p);//可用来向后生成链表,在表尾添加一个结点voidInsertOrder(Node*p);//按升序生成链表Node*CreatNode(Tdata);//创建一个结点(孤立结点)Node*DeleteNode(Node*p);//删除指定结点Node*RemoveAll(T&);//删除链表中所有数据域为指定值的结点Node*GetNode(int);//取出链表中第K个元素(从1开始计数)};templateList::List(){head=tail=new课后答案网Node();}templateList::~List(){www.hackshp.cnMakeEmpty();deletehead;}templatevoidList::MakeEmpty(){Node*tempP;while(head->link!=NULL){tempP=head->link;head->link=tempP->link;//把头结点后的第一个节点从链中脱离deletetempP;//删除(释放)脱离下来的结点}tail=head;//表头指针与表尾指针均指向表头结点,表示空链}templateNode*List::Find(Tdata){若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnNode*tempP=head->link;while(tempP!=NULL&&tempP->info!=data)tempP=tempP->link;returntempP;//搜索成功返回该结点地址,不成功返回NULL}templateintList::Length(){Node*tempP=head->link;intcount=0;while(tempP!=NULL){tempP=tempP->link;count++;}returncount;}templatevoidList::PrintList(){Node*tempP=head->link;while(tempP!=NULL){cout<info<<"t";tempP=tempP->link;}cout<voidList::InsertFront(Node*p){p->link=head->link;head->link=p;if(tail==head)tail=p;}templatevoidList::InsertRear(Node*p){p->link=tail->link;tail->link=p;课后答案网tail=p;}www.hackshp.cntemplatevoidList::InsertOrder(Node*p){Node*tempP=head->link,*tempQ=head;//tempQ指向tempP前面的一个节点while(tempP!=NULL){if(p->infoinfo)break;//找第一个比插入结点大的结点,由tempP指向tempQ=tempP;tempP=tempP->link;}tempQ->InsertAfter(p);//插在tempP指向结点之前,tempQ之后if(tail==tempQ)tail=tempQ->link;}templateNode*List::CreatNode(Tdata){//建立新节点Node*tempP=newNode(data);若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnreturntempP;}templateNode*List::DeleteNode(Node*p){Node*tempP=head;while(tempP->link!=NULL&&tempP->link!=p)tempP=tempP->link;if(tempP->link==tail)tail=tempP;returntempP->RemoveAfter();//本函数所用方法可省一个工作指针}templateNode*List::RemoveAll(T&p){//利用已有的DeleteNode()boolb=false;Node*TempP=head->link,*TempR=NULL;while(TempP!=NULL){//也可以利用尾指针if(TempP->info==p){deleteTempR;//释放上次找到的结点,第1次时因TempR为NULL不会出错TempR=DeleteNode(TempP);}TempP=TempP->link;}returnTempR;//仅返回最后一次找到的结点}templateNode*List::GetNode(inti){//取出链表中第K个元素(从1计数)Node*TempP=head->link;intj=1;if(i<0)returnNULL;if(i==0)returnhead;while(TempP!=NULL&&jlink;j++;}课后答案网returnTempP;}www.hackshp.cn//ep7_3.cpp#include"ep7_3.h"#includeusingnamespacestd;intmain(){constinth=9;inti;Listlist1;Node*n1,*P1;stringm("东南大学"),sp[h]={"南京大学","东南大学","交通大学","清华大学","天津大学","东南大学","复旦大学","浙江大学","同济大学"};cout<<"按原始数据次序输出:"<Getinfo()<<"”的结点。"<>i;n1=list1.GetNode(i);if(n1!=NULL)cout<Getinfo()<www.hackshp.cnusingnamespacestd;//首先看结点组织,采用结点类,凡与结点数据和指针操作有关函数作为成员函数templateclassList;templateclassNode{Tinfo;//数据域Node*link;//指针域public:Node();//生成头结点的构造函数Node(constT&data);//生成一般结点的构造函数voidInsertAfter(Node*P);//在当前结点后插入一个结点Node*RemoveAfter();//删除当前结点的后继结点,返回该结点备用T&Getinfo();//增加取数据域函数friendclassList;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn//以List为友元类,List可直接访问Node的私有函数,与结构一样方便,但更安全};templateNode::Node(){link=NULL;}templateNode::Node(constT&data){info=data;link=NULL;}templatevoidNode::InsertAfter(Node*p){p->link=link;link=p;}templateNode*Node::RemoveAfter(){Node*tempP=link;if(link==NULL)tempP=NULL;//已在链尾,后面无结点elselink=tempP->link;returntempP;}templateT&Node::Getinfo(){returninfo;}//增加取数据域函数//再定义链表类,选择常用操作:包括建立有序链表、搜索遍历、插入、删除、取数据等templateclassList{Node*head,*tail;//链表头指针和尾指针public:List();//构造函数,生成头结点(空链表)List(List&);//拷贝构造函数~List();//析构函数List&operator=(List&);voidMakeEmpty();//清空一个链表,只余表头结点Node*Find(Tdata);课后答案网//搜索数据域与data相同的结点,返回该结点的地址intLength();www.hackshp.cn//计算单链表长度voidPrintList();//打印链表的数据域voidInsertFront(Node*p);//可用来向前生成链表,在表头插入一个结点voidInsertRear(Node*p);//可用来向后生成链表,在表尾添加一个结点voidInsertOrder(Node*p);//按升序生成链表Node*CreatNode(Tdata);//创建一个结点(孤立结点)Node*DeleteNode(Node*p);//删除指定结点Node*RemoveAll(T&);/*删除链表中所有数据域为指定值的结点*/Node*GetNode(int);/*取出链表中第K个元素(从1开始计数)*/};templateList::List(){head=tail=newNode();}templateList::List(List&ls){//拷贝构造函数若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnNode*TempP=ls.head->link,*P1;head=tail=newNode();while(TempP!=NULL){P1=newNode(TempP->info);P1->link=tail->link;//向后生成list1tail->link=P1;tail=P1;TempP=TempP->link;}}templateList::~List(){MakeEmpty();deletehead;}templateList&List::operator=(List&ls){Node*TempP=ls.head->link,*P1;MakeEmpty();while(TempP!=NULL){P1=newNode(TempP->info);P1->link=tail->link;//向后生成list1tail->link=P1;tail=P1;TempP=TempP->link;}return*this;}templatevoidList::MakeEmpty(){Node*tempP;课后答案网while(head->link!=NULL){tempP=head->link;www.hackshp.cnhead->link=tempP->link;//把头结点后的第一个节点从链中脱离deletetempP;//删除(释放)脱离下来的结点}tail=head;//表头指针与表尾指针均指向表头结点,表示空链}templateNode*List::Find(Tdata){Node*tempP=head->link;while(tempP!=NULL&&tempP->info!=data)tempP=tempP->link;returntempP;//搜索成功返回该结点地址,不成功返回NULL}templateintList::Length(){Node*tempP=head->link;intcount=0;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnwhile(tempP!=NULL){tempP=tempP->link;count++;}returncount;}templatevoidList::PrintList(){Node*tempP=head->link;while(tempP!=NULL){cout<info<<"t";tempP=tempP->link;}cout<voidList::InsertFront(Node*p){p->link=head->link;head->link=p;if(tail==head)tail=p;}templatevoidList::InsertRear(Node*p){p->link=tail->link;tail->link=p;tail=p;}templatevoidList::InsertOrder(Node*p){Node*tempP=head->link,*tempQ=head;//tempQ指向tempP前面的一个节点while(tempP!=NULL){if(p->infoinfo)课后答案网break;//找第一个比插入结点大的结点,由tempP指向tempQ=tempP;tempP=tempP->link;www.hackshp.cn}tempQ->InsertAfter(p);//插在tempP指向结点之前,tempQ之后if(tail==tempQ)tail=tempQ->link;}templateNode*List::CreatNode(Tdata){//建立新节点Node*tempP=newNode(data);returntempP;}templateNode*List::DeleteNode(Node*p){Node*tempP=head;while(tempP->link!=NULL&&tempP->link!=p)tempP=tempP->link;if(tempP->link==tail)tail=tempP;returntempP->RemoveAfter();若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}//本函数所用方法可省一个工作指针,与InsertOrder比较templateNode*List::RemoveAll(T&p){/*利用已有的DeleteNode()*/boolb=false;Node*TempP=head->link,*TempR=NULL;while(TempP!=NULL){//也可以利用尾指针if(TempP->info==p){deleteTempR;TempR=DeleteNode(TempP);}TempP=TempP->link;}returnTempR;}templateNode*List::GetNode(inti){//取出链表中第K个元素(从1开始)Node*TempP=head->link;intj=1;if(i<0)returnNULL;if(i==0)returnhead;while(TempP!=NULL&&jlink;j++;}returnTempP;}//ep7_4.cpp#include"ep7_4.h"intmain(){Node*P1;Listlist1;课后答案网inta[16],i;cout<<"请输入16个整数www.hackshp.cn"<>a[i];//随机输入16个整数for(i=0;i<16;i++){P1=list1.CreatNode(a[i]);list1.InsertRear(P1);//向前生成list1}cout<<"输出list1:"<list2(list1),list3;list3=list1;list1.MakeEmpty();//清空原链表,看是否深拷贝cout<<"如无输出list1已清空:"<usingnamespacestd;//首先看结点组织,采用结点类,请参看习题7.3templateclassList;templateclassNode{……};//再定义链表类,凡是习题7.3~4中已给出的成员函数不再重复templateclassList{Node*head,*tail;//链表头指针和尾指针public:List();//构造函数,生成头结点(空链表)……voidReverse();//翻转链表};课后答案网templatevoidList::Reverse(){//链表翻转函数Node*p1,*tempP,*tempQ;www.hackshp.cnif(head==tail||head->link==tail)return;//空链表和单结点链表不必处理p1=newNode();p1->link=head->link;//p1形成一个过渡带头结点的链表tail=head;head->link=NULL;while(p1->link!=NULL){//链表有头结点可以保证算法无特殊结点tempP=p1;while(tempP->link!=NULL){tempQ=tempP;tempP=tempP->link;};//找到p1链的链尾tempP;tempQ->link=NULL;//p1结点后的第一个节点从链中脱离InsertRear(tempP);//脱离下来的结点重新向前生成翻转后的若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn新链表}}//ep7_5.cpp#include"ep7_5.h"intmain(){Node*P1;Listlist1;inta[16],i;cout<<"请输入16个整数"<>a[i];//随机输入16个整数,有重复的for(i=0;i<16;i++){P1=list1.CreatNode(a[i]);list1.InsertRear(P1);//向前生成list1}cout<<"输出list1:"<voidList::Reverse(){//链表翻转函数Node*p1,*tempP;if(head==tail||head->link==tail)return;//空链表和单结点链表不必处理p1=head->link;//p1指针指向第一个元素,形成一个无头结点的过渡链表tail=head;课后答案网head->link=NULL;while(p1!=NULL){www.hackshp.cntempP=p1;p1=tempP->link;//p1结点后的第一个节点从链中脱离InsertFront(tempP);//脱离下来的结点重新向前生成翻转后的新链表}}7.6为单链表重载“+”运算符,实现两个单链表对象的连接,但要去除数据域相同的结点。可用友元函数。解:为了实现ls3=ls1+ls2,需重载=和+两个运算符。=运算符先清空左边的链表,再模仿拷贝构造函数的编法编程。+运算符先建立一个局部链表,拷入被加链表,再以加链表的数据域生成局部链表后面的结点,最后去除数据域相同的结点。注意:当采用友元函数重载+运算符时,尽管重载函数是List的友元,而List是Node若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn的友类,但因为友元关系是不能传递的,还是不能访问Node的私有成员,必须通过Node的接口函数去间接访问。//ep7_6.h#includeusingnamespacestd;templateclassList;templateclassNode{……public:……Node*Getlink(){returnlink;}//取指针域};templateclassList{Node*head,*tail;//链表头指针和尾指针public:List();//构造函数,生成头结点(空链表)……List&operator=(List&);//重载=运算符friendListoperator+(List&,List&);//重载+运算符};templateList&List::operator=(List&ls){//重载=运算符Node*TempP=ls.head->link,*P1;MakeEmpty();//清空后tail=headwhile(TempP!=NULL){P1=newNode(TempP->info);P1->link=tail->link;//向后生成list1tail->link=P1;tail=P1;TempP=TempP->link;课后答案网}return*this;www.hackshp.cn}templateListoperator+(List&ls1,List&ls2){//重载+运算符Listls(ls1);//新链表,生命期仅在本函数域中Node*P1=ls2.head->Getlink(),*P2,*P3;//虽然本函数是List的友元,而List是Node的友类,但还是不能访问Node的私有成员while(P1!=NULL){P2=ls.CreatNode(P1->Getinfo());ls.InsertRear(P2);//向后生成list1P1=P1->Getlink();}P1=ls.head->Getlink();//删去重复的结点。while(P1!=NULL){若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnP2=P1->Getlink();while(P2!=NULL){//与后面结点逐个比较if(P1->Getinfo()==P2->Getinfo()){//有重复的就删去;P3=P2->Getlink();//删去后P2空悬ls.DeleteNode(P2);P2=P3;}P2=P2->Getlink();//到后面一个结点}P1=P1->Getlink();//再用第二个....}//先用第一个结点,与后面结点逐个比较,有重复的就删去;再用第二个....returnls;//为保证返回时用拷贝构造函数复制一个链表返回,返回类型不能是引用,}//ep7_6.cpp#include"ep7_6.h"intmain(){Node*P1;Listlist1,list2,list;inta[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},i;for(i=0;i<16;i++){P1=list1.CreatNode(a[i]);list1.InsertRear(P1);//向后生成list1}cout<<"输出list1:"<&,DblList&);#includeusingnamespacestd;templateclassDblList;templateclassDblNode{//结点类Tinfo;//数据域若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnDblNode*llink,*rlink;//前驱(左链)、后继(右链)指针public:DblNode(Tdata);DblNode();TGetinfo(){returninfo;};friendclassDblList;};templateDblNode::DblNode(){llink=rlink=NULL;}templateDblNode::DblNode(Tdata){info=data;llink=NULL;rlink=NULL;}templateclassDblList{//双链表类DblNode*head,*current;public:DblList();~DblList();voidInsert(constT&data);DblNode*Remove(DblNode*p);voidPrint();intLength();//计算链表长度DblNode*Find(Tdata);//搜索数据与定值相同的结点voidMakeEmpty();//清空链表voidMerge(DblList&,DblList&);//归并//其它操作};课后答案网templateDblList::DblList(){//建立表头结点head=newDblNode();www.hackshp.cnhead->rlink=head->llink=head;current=NULL;}templateDblList::~DblList(){MakeEmpty();//清空链表deletehead;}templatevoidDblList::MakeEmpty(){DblNode*tempP;while(head->rlink!=head){tempP=head->rlink;head->rlink=tempP->rlink;//把头结点后的第一个节点从链中脱离tempP->rlink->llink=head;//处理左指针若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cndeletetempP;//删除(释放)脱离下来的结点}current=NULL;//current指针恢复}templatevoidDblList::Insert(constT&data){//新节点在链尾current=newDblNode;current->info=data;current->rlink=head;//注意次序current->llink=head->llink;head->llink->rlink=current;head->llink=current;//最后做}templateDblNode*DblList::Remove(DblNode*p){current=head->rlink;while(current!=head&¤t!=p)current=current->rlink;if(current==head)current=NULL;else{//结点摘下p->llink->rlink=p->rlink;p->rlink->llink=p->llink;p->rlink=p->llink=NULL;}returncurrent;}templateDblNode*DblList::Find(Tdata){current=head->rlink;while(current!=head&¤t->info!=data)current=current->rlink;if(current==head)current=NULL;returncurrent;}课后答案网templatevoidDblList::Print(){current=head->rlink;www.hackshp.cnwhile(current!=head){cout<info<<"t";current=current->rlink;}cout<intDblList::Length(){intcount=0;current=head->rlink;while(current!=head){count++;current=current->rlink;}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnreturncount;}templatevoidDblList::Merge(DblList&dbl1,DblList&dbl2){//归并DblNode*tdp1=dbl1.head->rlink,*tdp2=dbl2.head->rlink;while(tdp1!=dbl1.head&&tdp2!=dbl2.head)if(tdp1->infoinfo){Insert(tdp1->info);tdp1=tdp1->rlink;}else{Insert(tdp2->info);tdp2=tdp2->rlink;}if(tdp1!=dbl2.head)while(tdp1!=dbl1.head){Insert(tdp1->info);tdp1=tdp1->rlink;}if(tdp2!=dbl2.head)while(tdp2!=dbl2.head){Insert(tdp2->info);tdp2=tdp2->rlink;}}intmain(){DblListDbl1,Dbl2,Dbl3;DblNode*tp=NULL;inti,a[11]={9,11,17,23,27,32,33,35,43,51,59};intb[11]={1,3,12,13,17,24,30,45,53,63,69};for(i=0;i<11;i++)Dbl1.Insert(a[i]);cout<<"双向链表长度:课后答案网"<Getinfo()<<"清除"<#includeusingnamespacestd;templateclassStack{inttop;//栈顶指针(下标)T*elements;//指向动态建立的数组的指针intmaxSize;//栈最大允纳的元素个数public:Stack(int=20);//栈如不指定大小,设为20元素~Stack(){delete[]elements;}voidPush(constT&data);//压栈TPop();//弹出,top--TGetElem(inti);//取数据,top不变voidStackFull();//堆栈加倍voidMakeEmpty(){top=-1;}//清空栈boolIsEmpty()const{returntop==-1;}//判栈空boolIsFull()const{returntop==maxSize-1;}//判栈满voidPrintStack();//输出栈内所有数据};templateStack::Stack(intmaxs){maxSize=maxs;课后答案网top=-1;elements=newT[maxSize];www.hackshp.cn//建立栈空间assert(elements!=0);//分配不成功结束程序}templatevoidStack::PrintStack(){for(inti=0;i<=top;i++)cout<voidStack::Push(constT&data){if(IsFull()){cout<<"栈满"<TStack::Pop(){assert(!IsEmpty());//栈已空则不能退栈,退出程序returnelements[top--];//返回栈顶元素,同时栈顶指针退1}templateTStack::GetElem(intI){assert(i<=top&&i>=0);//超出栈有效范围则出错,退出程序returnelements[i];//返回栈中指定元素,top不变}templatevoidStack::StackFull(){//堆栈加倍T*el=elements;inti=maxSize,j;maxSize*=2;elements=newT[maxSize];//建立栈空间assert(elements!=0);//分配不成功结束程序for(j=0;jistack(5);for(i=0;i<25;i++)istack.Push(a[i]);istack.PrintStack();i=0;while(!istack.IsEmpty()){b[i]=istack.Pop();i++;}if(istack.IsEmpty())cout<<"课后答案网栈空"<classStack{seqliststack;public:Stack(intmaxs=20):stack(maxs){};//栈如不指定大小,设为20元素~Stack(){}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnvoidPush(constT&data){stack.Push_back(data);}//压栈TPop(){returnstack.Pop_back();}//弹出TGetElem(inti){returnstack.GetElem(i);}//取数据boolIsEmpty()const{returnstack.IsEmpty();}//判栈空boolIsFull()const{returnstack.IsFull();}//判栈满voidPrintStack(){stack.Printseqlist();}//输出栈内所有数据};intmain(){inti,a[25]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24},b[25];Stackistack(5);for(i=0;i<25;i++)istack.Push(a[i]);istack.PrintStack();i=0;while(!istack.IsEmpty()){b[i]=istack.Pop();i++;}if(istack.IsEmpty())cout<<"栈空"<#includeusingnamespacestd;templateclassseqlist{intlast;//顺序表最大下标T*elements;课后答案网//动态建立的数组intmaxSize;//顺序表最大允纳的元素个数public:www.hackshp.cnseqlist(int=20);//顺序表如不指定大小,设为20元素~seqlist(){delete[]elements;}voidPush_back(constT&data);//顺序表添加一个元素TPop_back();//顺序表弹出一个元素,top--TGetElem(inti);//取数据,last不变voidseqlistFull();//顺序表加倍voidMakeEmpty(){last=-1;}//清空顺序表boolIsEmpty()const{returnlast==-1;}//判顺序表空boolIsFull()const{returnlast==maxSize-1;}//判顺序表满voidPrintseqlist();//输出顺序表内所有数据};templateseqlist::seqlist(intmaxs){maxSize=maxs;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnlast=-1;elements=newT[maxSize];//建立栈空间assert(elements!=0);//分配不成功结束程序}templatevoidseqlist::Printseqlist(){for(inti=0;i<=last;i++)cout<voidseqlist::Push_back(constT&data){if(IsFull()){cout<<"顺序表满"<Tseqlist::Pop_back(){assert(!IsEmpty());//顺序表已空则不能弹出,退出程序returnelements[last--];//返回顺序表最后一个元素,同时last减1}templateTseqlist::GetElem(inti){assert(i<=last&&i>=0);//超出顺序表有效范围则出错,退出程序returnelements[i];//返回顺序表指定元素}templatevoidseqlist::seqlistFull(){//顺序表加倍T*el=elements;inti=maxSize,j;maxSize*=2;elements=new课后答案网T[maxSize];//建立顺序表空间assert(elements!=0);//分配不成功结束程序for(j=0;j#includeusingnamespacestd;templateclassQueue;templateclassNode{Tinfo;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnNode*link;public:Node(){link=NULL;}Node(Tdata,Node*l=NULL);friendclassQueue;};templateNode::Node(Tdata,Node*l){info=data;link=l;};templateclassQueue{Node*front,*rear;public:Queue(){rear=front=NULL;}//构造一个空链队~Queue();boolIsEmpty(){returnfront==NULL;}//队空否?voidEnQue(constT&);//进队TDeQue();//出队TGetFront();//查看队头数据voidMakeEmpty();//置空队列,与析构逻辑上不同,物理上一样voidEnQueFront(constT&);//从队头入队};templatevoidQueue::MakeEmpty(){Node*temp;while(front!=NULL){课后答案网temp=front;front=front->link;deletetemp;}www.hackshp.cn}templateQueue::~Queue(){MakeEmpty();}templatevoidQueue::EnQue(constT&data){if(front==NULL)front=rear=newNode(data,NULL);elserear=rear->link=newNode(data,NULL);}templatevoidQueue::EnQueFront(constT&data){//从队头入队Node*p=newNode(data,NULL);if(front==NULL)front=rear=p;else{p->link=front;front=p;}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}templateTQueue::DeQue(){assert(!IsEmpty());Node*temp=front;Tdata=temp->info;front=front->link;deletetemp;returndata;}templateTQueue::GetFront(){assert(!IsEmpty());returnfront->info;}intmain(){inti;Queueque;charstr1[]="abcdefghijklmnop";//18元素数组,17个字符,再加串结束符for(i=0;i<17;i++)que.EnQue(str1[i]);for(i=0;i<17;i++)que.EnQueFront(str1[i]);while(!que.IsEmpty())cout<classQueue{www.hackshp.cnlistque;public:Queue():que(){}//构造一个空链队~Queue(){};boolIsEmpty(){returnque.IsEmpty();}//队空否?voidEnQue(constT&data){que.EnRear(data);}//进队TDeQue(){returnque.DeFront();}//出队TGetFront(){returnque.GetFront();}//查看队头数据voidMakeEmpty(){que.MakeEmpty();}//置空队列,与析构逻辑上不同,物理上一样voidEnQueFront(constT&data){que.EnFront(data);}//从队头入队};intmain(){inti;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnQueueque;charstr1[]="abcdefghijklmnop";//18元素数组,17个字符,再加串结束符for(i=0;i<17;i++)que.EnQue(str1[i]);for(i=0;i<17;i++)que.EnQueFront(str1[i]);while(!que.IsEmpty())cout<#includeusingnamespacestd;templateclassQueue;templateclassNode{Tinfo;Node*link;public:Node(){link=NULL;}Node(Tdata,Node*l=NULL);TGetinfo(){returninfo;};//获得结点数据Node*Getlink(){returnlink;};//获得结点的指针voidSetinfo(Tdata){info=data};//设置结点数据voidSetlink(Node*pNext){link=pNext;}//设置结点的指针};templateNode::Node(Tdata,Node*l){info=data;link=l;};课后答案网templateclasslist{Node*front,*rear;www.hackshp.cnpublic:list(){rear=front=NULL;}//构造一个空链~list();boolIsEmpty(){returnfront==NULL;}//链空否?voidEnRear(constT&);//进链TDeFront();//出链TGetFront();//查看链头数据voidMakeEmpty();//置空链,与析构逻辑上不同,物理上一样voidEnFront(constT&);//从链头入链若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn};templatevoidlist::MakeEmpty(){Node*temp;while(front!=NULL){temp=front;front=front->Getlink();deletetemp;}}templatelist::~list(){MakeEmpty();}templatevoidlist::EnRear(constT&data){if(front==NULL)front=rear=newNode(data,NULL);else{rear->Setlink(newNode(data,NULL));rear=rear->Getlink();}}templatevoidlist::EnFront(constT&data){//从链头入链Node*p=newNode(data,NULL);if(front==NULL)front=rear=p;else{p->Setlink(front);front=p;}}templateTlist::DeFront(){assert(!IsEmpty());Node*temp=front;Tdata=temp->Getinfo();front=front->Getlink();deletetemp;课后答案网returndata;}www.hackshp.cntemplateTlist::GetFront(){assert(!IsEmpty());returnfront->Getinfo();}7.10为二叉树类编写统计其度为2的结点数n2的成员函数,统计叶结点数n0的成员函数。并验证n0=n2+1。解:证明:二叉树结点总数:n=n0+n1+n2另有1度结点有1个孩子,2度结点有2孩子,二叉树孩子结点总数为:n1+2n2二叉树仅有根结点不是孩子结点,所以:n=n1+2n2+1所以:n=n0+n1+n2=n1+2n2+1若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn即:n0=n2+1//此题将两成员函数定为私有,在公有部分加接口函数#include#includeusingnamespacestd;templateclassBinaryTree;templateclassNode{Node*lchild,*rchild;Tinfo;public:Node(){lchild=NULL;rchild=NULL;}Node(Tdata,Node*left=NULL,Node*right=NULL){info=data;lchild=left;rchild=right;}friendclassBinaryTree;};templateclassBinaryTree{Node*root;//二叉树的根指针voidInsert(constT&data,Node*&b);//插入结点,参数为引用!voidDestory(Node*Current);//删除树intCountleaf(Node*btree);//叶结点计数intCountNode2(Node*btree);//度为2的结点计数public:BinaryTree(){root=NULL;}//空树构造函数~BinaryTree(){Destory(root);}//析构函数voidCreat(T*data,intn);//建立(排序)二叉树intCountleaf(){课后答案网returnCountleaf(root);}//叶结点计数接口intCountNode2(){returnCountNode2(root);}//度为2的结点计数接口};www.hackshp.cntemplatevoidBinaryTree::Destory(Node*Current){if(Current!=NULL){Destory(Current->lchild);Destory(Current->rchild);deleteCurrent;//后序释放根结点}}templatevoidBinaryTree::Insert(constT&data,Node*&b){if(b==NULL){//已到空树,插入b=newNode(data);if(b==NULL){cout<<"空间不足"<info)Insert(data,b->lchild);//小于,向左子树去查elseInsert(data,b->rchild);//大于等于,向右子树去查}templatevoidBinaryTree::Creat(T*data,intn){//建立一棵二叉排序树for(inti=0;iintBinaryTree::Countleaf(Node*btree){//叶结点计数intnum1,num2;if(btree==NULL)return0;elseif(btree->lchild==NULL&&btree->rchild==NULL)return1;else{num1=Countleaf(btree->lchild);num2=Countleaf(btree->rchild);return(num1+num2);}}templateintBinaryTree::CountNode2(Node*btree){//度为2的结点计数intnum=0;if(btree!=NULL){if(btree->lchild!=NULL&&btree->rchild!=NULL)num+=1;;num+=CountNode2(btree->lchild);num+=CountNode2(btree->rchild);}returnnum;}intmain(){课后答案网constintn=15;inti,a[n]={10,5,15,8,3,18,13,12,14,16,20,1,4,6,9};www.hackshp.cnBinaryTreebtree;btree.Creat(a,n);cout<<"输入数据:"<#includeusingnamespacestd;templateclassBinaryTree;templateclassNode{Node*lchild,*rchild;Tinfo;public:Node(){lchild=NULL;rchild=NULL;}Node(Tdata,Node*left=NULL,Node*right=NULL){info=data;lchild=left;rchild=right;}friendclassBinaryTree;};templateclassBinaryTree{Node*root;//二叉树的根指针voidInOrder(Node*Current);//中序遍历voidPreOrder(Node*Current);//前序遍历voidPostOrder(Node*Current);//后序遍历voidInsert(constT&data,Node*&b);//插入结点,参数为引用!voidDestory(Node*Current);//删除树Node*Copy(Node*snode);public:BinaryTree(){root=NULL;}//空树构造函数BinaryTree(BinaryTree&);//拷贝构造函数~BinaryTree(){Destory(root);}课后答案网//析构函数BinaryTree&operator=(BinaryTree&);voidDestory(){Destory(root);root=NULL;}www.hackshp.cn//删除树后root悬挂,必须赋空voidCreat(T*data,intn);//建立(排序)二叉树voidInOrder(){InOrder(root);}//中序遍历,共有函数为接口voidPreOrder(){PreOrder(root);}//前序遍历,共有函数为接口voidPostOrder(){PostOrder(root);}//后序遍历,共有函数为接口};templateBinaryTree::BinaryTree(BinaryTree&sb){//拷贝构造函数root=Copy(sb.root);}templateNode*BinaryTree::Copy(Node*snode){if(snode==NULL)returnNULL;Node*p=newNode;p->info=snode->info;p->lchild=Copy(snode->lchild);若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnp->rchild=Copy(snode->rchild);returnp;}templateBinaryTree&BinaryTree::operator=(BinaryTree&sb){root=Copy(sb.root);return*this;}templatevoidBinaryTree::Destory(Node*Current){if(Current!=NULL){Destory(Current->lchild);Destory(Current->rchild);deleteCurrent;//后序释放根结点}}templatevoidBinaryTree::Insert(constT&data,Node*&b){if(b==NULL){//已到空树,插入b=newNode(data);if(b==NULL){cout<<"空间不足"<info)Insert(data,b->lchild);//小于,向左子树去查elseInsert(data,b->rchild);//大于等于,向右子树去查}templatevoidBinaryTree::Creat(T*data,intn){/建立一棵二叉排序树for(inti=0;ivoidBinaryTree::InOrder(Node*Current){if(Current!=NULL){www.hackshp.cn//递归终止条件InOrder(Current->lchild);//中序遍历左子树cout<info<<"t";//访问根结点,注意所放位置InOrder(Current->rchild);//中序遍历右子树}}templatevoidBinaryTree::PreOrder(Node*Current){if(Current!=NULL){cout<info<<"t";//注意前序访问语句所放位置若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnPreOrder(Current->lchild);PreOrder(Current->rchild);}}templatevoidBinaryTree::PostOrder(Node*Current){if(Current!=NULL){PostOrder(Current->lchild);PostOrder(Current->rchild);cout<info<<"t";//后序访问根结点}}intmain(){constintn=15;inti,a[n]={10,5,15,8,3,18,13,12,14,16,20,1,4,6,9};BinaryTreebtree;btree.Creat(a,n);cout<<"输入数据:"<btree1(btree),btree2;btree2=btree;btree.Destory();//删去原树,看是否深拷贝cout<#includeusingnamespacestd;templateclassBinaryTree;templateclassNode{Node*lchild,*rchild;Tinfo;public:Node(){lchild=NULL;rchild=NULL;}Node(Tdata,Node*left=NULL,Node*right=NULL){info=data;lchild=left;rchild=right;}friendclassBinaryTree;};templateclassBinaryTree{Node*root;//二叉树的根指针voidInsert(constT&data,Node*&b);//插入结点,参数为引用!voidDestory(Node*Current);//删除树intCountdepth(Node*btree);//树深度计数public:BinaryTree(){root=NULL;}//空树构造函数~BinaryTree(){Destory(root);}//析构函数voidCreat(T*data,intn);//建立(排序)二叉树intCountdepth(){课后答案网returnCountdepth(root);}//树深度计数};templatevoidBinaryTree::Destory(Node*Current){www.hackshp.cnif(Current!=NULL){Destory(Current->lchild);Destory(Current->rchild);deleteCurrent;//后序释放根结点}}templatevoidBinaryTree::Insert(constT&data,Node*&b){if(b==NULL){//已到空树,插入b=newNode(data);if(b==NULL){cout<<"空间不足"<info)Insert(data,b->lchild);//小于,向左子树去查elseInsert(data,b->rchild);//大于等于,向右子树去查}templatevoidBinaryTree::Creat(T*data,intn){//建立一棵二叉排序树for(inti=0;iintBinaryTree::Countdepth(Node*btree){//树深度intnum1,num2;if(btree==NULL)return0;elseif(btree->lchild==NULL&&btree->rchild==NULL)return1;else{num1=Countdepth(btree->lchild)+1;num2=Countdepth(btree->rchild)+1;if(num1>num2)returnnum1;elsereturnnum2;}}intmain(){constintn=15;inti,a[n]={10,5,15,8,3,18,13,12,14,16,20,1,4,6,9};BinaryTreebtree;//按排序二叉树生成,共4个层次btree.Creat(a,n);cout<<"输入数据:"<课后习题答案www.hackshp.cn第八章继承与多态习题一.基本概念与基础知识自测题8.18.1填空题8.1.1如果类α继承了类β,则类α称为(1)类,而类β称为(2)类。(3)类的对象可作为(4)类的对象处理,反过来不行,因为(5)。如果强制转换则要注意(6)。答案:(1)基类(2)派生类(3)派生类(4)基类(5)派生类有一些新成员(6)只能派生类强制转换为基类若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn8.1.2当用public继承从基类派生一个类时,基类的public成员成为派生类的(1)成员,protected成员成为派生类的(2)成员,对private成员是(3)。公有派生可以使其类的(4),所以公有派生是主流。答案:(1)public成员(2)protected成员(3)不可访问(4)接口不变8.1.3利用继承能够实现(1)。这种实现缩短了程序开发的时间,VC++中的(2)很好地体现了这一点。答案:(1)代码的复用(2)MFC编程8.1.4一个派生类只有一个直接基类的情况称为(1),而有多个直接基类的情况称为(2)。继承体现了类的(3)概念,这在MFC中得到了很好表现,MFC中只采用了(4)。答案:(1)单继承(2)多重继承(3)层次(4)单继承8.1.5C++中多态性包括两种多态性:(1)和(2)。前者是通过(3)实现的,而后者是通过(4)和(5)来实现的。答案:(1)编译时的(2)运行时的(3)函数和运算符的重载(4)类继承关系(5)虚函数课后答案网8.1.6在基类中将一个成员函数说明成虚函数后,在其派生类中只要(1)、(2)和(3)完全一样就认为是虚函数,而不必再加关键字(www.hackshp.cn4)。如有任何不同,则认为是(5)而不是虚函数。除了非成员函数不能作为虚函数外,(6)、(7)和(8)也不能作为虚函数。答案:(1)同虚函数名(2)同参数表(3)同返回类型。如基类中返回基类指针,而派生类中返回派生类指针是允许的(4)virtual(5)重载(6)静态成员函数(7)内联函数(8)构造函数8.1.7纯虚函数定义时在函数参数表后加(1),它表明程序员对函数(2),其本质是将指向函数体的指针定为(3)。若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn答案:(1)=0(2)不定义(3)NULL8.18.1简答题8.1.1构造函数和析构函数可以继承吗?派生类构造函数各部分的执行次序是怎样的?答:构造函数和析构函数不可以继承。派生类构造函数各部分的执行次序是:1.调用基类构造函数,按它们在派生类声明的先后顺序,依次调用。2.调用新增成员对象的构造函数,按它们在类定义中声明的先后顺序,依次调用。3.派生类的构造函数体中的操作。8.1.2什么叫派生类的同名覆盖(override)?答:如果派生类声明了一个和某个基类成员同名的新成员(当然如是成员函数,参数表也必须一样,否则是重载),派生类中的新成员就屏蔽了基类同名成员,类似函数中的局部变量屏蔽全局变量。称为同名覆盖(override)。8.1.3派生类的析构函数中需完成什么任务?是否要编写对基数和成员对象的析构函数的调用?为什么?答:析构函数的功能是作善后工作,析构函数无返回类型也没有参数,情况比较简单。派生类析构函数定义格式与非派生类无任何差异,不要编写对基数和成员对象的析构函数的调用,只要在函数体内把派生类新增一般成员处理好就可以了,因为对新增的成员对象和基类的善后工作,系统会自己调用成员对象和基类的析构函数来完成。8.1.4为什么要使用虚基类?怎样定义虚基类?用一个实例来解释虚基类在其派生类中的存储方式。答:在多重继承是有可能出现同一基类的两个拷贝,为避免这种情况,可使用虚基类。虚基类(virtualbaseclass)定义方式如下:class派生类名:virtual课后答案网访问限定符基类类名{...};class派生类名:访问限定符virtual基类类名{...};virtual关键字只对紧随其后的基类名起作用。www.hackshp.cn如下派生:存储关系如(b),在职研究生类有两个Person拷贝。采用虚基类后存储关系如下:采用虚基类后在职研究生类储存图StudentGStudent若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnEGStudentPersonStudent新成员GStudent新成员PersonEmployee新成员Person成员EGStudent新成员PersonPerson课后答案网Employeewww.hackshp.cn若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn在职研究生类只有一个Person拷贝。8.1.5简单叙述派生类与基类的赋值兼容规则。答:凡是基类所能解决的问题,公有派生类都可以解决。在任何需要基类对象的地方都可以用公有派生类的对象来代替,这条规则称赋值兼容规则。它包括以下情况:1.派生类的对象可以赋值给基类的对象,这时是把派生类对象中从对应基类中继承来的成员赋值给基类对象。反过来不行,因为派生类的新成员无值可赋。2.可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的成员,不能访问派生类中的新成员。同样也不能反过来做。3.派生类对象可以初始化基类的引用。引用是别名,但这个别名只能包含派生类对象中的由基类继承来的成员。8.1.6在类中定义对象成员称为复合或嵌套,请对比复合与继承的异同之处。答:成员对象是嵌套的概念,使用成员对象中的成员,只能直接访问(对象名加点号加成员名)公有成员。在类的成员函数中不能直接访问和处理成员对象的私有和保护成员,而要通过成员对象的接口去间接访问和处理。某些应用中,对象成员可以代替继承中的基类。基类在派生类中只能继承一个(间接基类不在讨论之中)不能同时安排两个,否则成员名即使使用域分辨符也会发生冲突,但如果一定要用两个,只能采用成员对象。所以采用成员对象更加灵活。两者不是对立的,而是互为补充的。8.1.7比较派生与模板各自的优点。答:模板追求的是运行效率,而派生追求的是编程的效率。课后答案网通用性是模板库的设计出发点之一,这是由泛型算法和函数对象等手段达到的。为了运行的效率,类模板是相互独立的,即独立设计,没有使用继承的思想。对类模板的扩展是采用适配子(adapter)来完成的。应该说派生类的目标之一也是代码的复用和程序的通用性www.hackshp.cn,最典型的就是MFC,派生类的优点是可以由简到繁,逐步深入,程序编制过程中可以充分利用前面的工作,一步步完成一个复杂的任务。8.1.8是否使用了虚函数就能实现运行时的多态性?怎样才能实现运行时的多态性?答:不是。实现动态多态性时,必须使用基类类型的指针变量或引用,使该指针指向该基类的不同派生类的对象,并通过该指针指向虚函数,才能实现动态的多态性。8.1.9为什么析构函数总是要求说明为虚函数?答:在基类中及其派生类中都动态分配内存空间时,必须把析构函数定义为虚函数,实现撤消对象时的多态性。根据赋值兼容规则可以用基类的指针指向派生类对象,如果由该指针撤销派生类对象,则必须将析构函数说明为虚函数,实现多态性,自动调用派生类析构函数。我们总是要求将类设计成通用的,无论其他程序员怎样调用都必须保证不出错,所以必须把析构函数定义为虚函数。若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn8.1.10什么是抽象类?含有纯虚函数的类是抽象类吗?答:若定义一个类,它只能用作基类来派生出新的类,而不能用来定义对象,则称为抽象类。含有纯虚函数的类是抽象类。8.1.11能否不提供源代码,做到用户自行把通用的软件转化为专用软件?怎样实现?答:能不提供源代码,做到用户自行把通用的软件转化为专用软件。动态联编不一定要源代码,可以只有头文件和对象文件的.obj文件。软件开发商可在不透露其秘密的情况下发行.obj形式的软件,然后由程序员利用继承机制,从所购得的类中派生出新类。能与软件开发商提供的类一起运行的软件也能与派生类一起运行,并能通过动态联编使用这些派生类中重定义的虚函数。比如通用的财务软件可以转化为某公司的专用软件。一.编程与综合练习题8.2请用类的派生方式来组织下列动物实体与概念:动物,脊椎动物亚门,节肢动物门,鱼纲,鸟纲,爬行纲,哺乳纲,昆虫纲,鲨鱼,青鱼,海马,鹦鹉,海鸥,喜鹊,蝙蝠,翼龙,蜻蜓,金龟,扬子鳄,袋鼠,金丝猴,虎,蜈蚣,蜘蛛,蝗虫,知了,螃蟹,虾。解:动物派生出:脊椎动物亚门和节肢动物门。脊椎动物亚门派生出:鱼纲,鸟纲,爬行纲,哺乳纲。鱼纲派生出:鲨鱼,青鱼,海马。鸟纲派生出:鹦鹉,海鸥,喜鹊。爬行纲派生出:翼龙,金龟,扬子鳄。哺乳纲派生出:蝙蝠,袋鼠,金丝猴,虎。节肢动物门派生出:昆虫纲,蜈蚣(多足纲),蜘蛛(蜘形纲),螃蟹,虾(甲壳纲)。昆虫纲派生出:蜻蜓,蝗虫,知了。8.3定义商品类及其多层的派生类。以商品类为基类。第一层派生出服装类、家电类、车辆类。第二层派生出衬衣类、外衣类、帽子类、鞋子类;空调类、电视类、音响类;自行车类、轿车类、摩托车类。要求给出基本属性和派生过程中增加的属性。课后答案网解:按题意没有操作,所以只列出数据成员,也不再检验#includewww.hackshp.cnusingnamespacestd;classCommodity{doubleprice;//价格charname[20];//商品名charmanufacturer[20];//生产厂家intitems;//数量};classClothing:publicCommodity{//服装类chartexture[20];//材料质地};classElectric_Appliance:publicCommodity{//家电类enum{Black,White}type;//黑白家电};若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnclassVehicle:publicCommodity{//车辆类intwheel_num;//车轮数量};classShirt:publicClothing{//衬衣类enum{Formal,Casual}Style;//式样:正式、休闲};classGarment:publicClothing{//外衣类enum{Jacket,Coat}Style;//式样:夹克、外套};classHat:publicClothing{//帽子类;enum{Winter,Summer,Spring_Autumn}Style;//季节风格};classShoes:publicClothing{//鞋子类enum{Winter,Summer,Spring_Autumn}Style;//季节风格};classAir_Cindition:publicElectric_Appliance{//空调boolwarm_cool;//是否冷暖floatpower;//功率};classTelevision:publicElectric_Appliance{//电视类intSize;//尺寸boolisColor;//是否彩色};classAcoustics:publicElectric_Appliance{//音响类intspeaker_num;//喇叭数目floatpower;//功率};classBicycle:publicVehicle{//自行车类intspeed_grades;课后答案网//调速级数intwheel_size;//轮子大小};www.hackshp.cnclassCar:publicVehicle{//轿车类floatvolume;//排气量boolisSkylight;//是否有天窗intbox_num;//厢数};classMotorcycle:publicVehicle{//摩托车类floatvolume;//排气量};intmain(){return0;}8.4以点(point)类为基类,重新定义矩形类和圆类。点为直角坐标点,矩形水平放置,若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn由左下方的顶点和长宽定义。圆由圆心和半径定义。派生类操作判断任一坐标点是在图形内,还是在图形的边缘上,还是在图形外。缺省初始化图形退化为点。要求包括拷贝构造函数。编程测试类设计是否正确。解:#include#includeusingnamespacestd;constdoublePI=3.1415926535;classPoint{private:doublex,y;public:Point(){x=0;y=0;}Point(doublexv,doubleyv){x=xv;y=yv;}Point(Point&pt){x=pt.x;y=pt.y;}doublegetx(){returnx;}doublegety(){returny;}doubleArea(){return0;}voidShow(){cout<<"x="<#includeusingnamespacestd;constdoublePI=3.1415926535;classGeometric_shape{//几何图形public:virtualdoubleperimeter()=0;//周长virtualdoublearea()=0;//面积virtualdoublevolume()=0;//体积virtualvoidShow(){};};classCircle:publicGeometric_shape{//圆若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cndoubleradius;public:Circle(){radius=0;}Circle(doublevv){radius=vv;}doubleperimeter(){return2.0*PI*radius;}//周长doublearea(){returnPI*radius*radius;}//面积doublevolume(){return0;}//体积voidShow(){cout<<"radius="<Show();cout<<"矩形周长:"<perimeter()<<"t";cout<<"矩形面积:"<area()<<"t";cout<<"矩形体积:"<volume()<Show();cout<<"三角形周长:"<perimeter()<<"t";cout<<"三角形面积:"<area()<<"t";cout<<"三角形体积:"<volume()<Show();cout<<"长方体底周长:"<perimeter()<<"t";cout<<"长方体底面积:"<area()<<"t";cout<<"长方体体积:"<volume()<Show();cout<<"圆柱体底周长:"<perimeter()<<"t";cout<<"圆柱体底面积:"<area()<<"t";cout<<"圆柱体体积:"<volume()<Show();cout<<"圆锥体底周长:"<perimeter()<<"t";cout<<"圆锥体底面积:"<area()<<"t";cout<<"圆锥体体积:"<volume()<Show();课后答案网cout<<"三棱锥底周长:"<perimeter()<<"t";cout<<"三棱锥底面积:www.hackshp.cn"<area()<<"t";cout<<"三棱锥体积:"<volume()<Show();cout<<"三棱柱底周长:"<perimeter()<<"t";cout<<"三棱柱底面积:"<area()<<"t";cout<<"三棱柱体积:"<volume()<#includeusingnamespacestd;staticintGrades[]={500,600,750,1000,1400,2000,2800,4000};classemployee{protected:stringname;//姓名intID;//职工号intgrade;//工资级别doublesalary;//月doublebase_salary;//基本月薪doublecareer_salary;课后答案网//业绩工资public:employee(string="",intwww.hackshp.cn=0,int=0);virtualvoidpay();//月薪计算函数voidshow();doublegetsalary(){returnsalary;}doublegetbase_salary(){returnbase_salary;}doublegetcareer_salary(){returncareer_salary;}};employee::employee(stringnn,intid,intgr){name=nn;ID=id;grade=gr;salary=0;//月薪base_salary=0;//基本月薪career_salary=0;//业绩工资若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}voidemployee::show(){cout<>days;base_salary=Grades[grade]*(23-days)/23;career_salary=base_salary/2;//普通员工业绩工资为基本工资的一半salary=base_salary+career_salary;}classmanager:virtualpublicemployee{//虚基类protected:doubleprize;//固定奖金额doublefactor;//业绩系数public:manager(string="",int=0,int=0,double=0);voidpay();};manager::manager(stringnn,intid,intgr,doublepr):employee(nn,id,gr){prize=pr;//固定奖金额factor=0;}voidmanager::pay(){intdays;cout<<"请输入请假天数:n";cin>>days;cout<<"请输入业绩系数课后答案网:n";cin>>factor;base_salary=Grades[grade]*(23-days)/23;www.hackshp.cncareer_salary=prize*factor*(23-days)/23;salary=base_salary+career_salary;}classtechnician:virtualpublicemployee{protected:doublehours;//月工作时数doubleperhour;//每小时附加酬金doubleshfactor;//研究进度系数public:technician(string="",int=0,int=0,double=0);voidpay();};technician::technician(stringnn,intid,intgr,doublephr):employee(nn,id,gr){若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnhours=0;perhour=phr;//每小时附加酬金shfactor=0;}voidtechnician::pay(){intdays;cout<<"请输入请假天数:n";cin>>days;cout<<"请输入研究进度系数:n";cin>>shfactor;hours=8*(23-days);base_salary=Grades[grade]*(23-days)/23;career_salary=perhour*hours*shfactor*(23-days)/23;salary=base_salary+career_salary;}classsalesman:virtualpublicemployee{protected:doubleamount;//销售额doubleslfactor;//提成比例public:salesman(string="",int=0,int=0,double=0);voidpay();};salesman::salesman(stringnn,intid,intgr,doubleslfac):employee(nn,id,gr){amount=0;slfactor=slfac;//提成比例}voidsalesman::pay(){课后答案网intdays;cout<<"请输入请假天数www.hackshp.cn:n";cin>>days;cout<<"请输入销售额:n";cin>>amount;base_salary=Grades[grade]*(23-days)/23;career_salary=amount*slfactor;salary=base_salary+career_salary;}classdevelopermanager:publicmanager,publictechnician{public:developermanager(string="",intid=0,intgr=0,doublepr=0,doublephr=0);voidpay();};developermanager::developermanager(stringnn,intid,intgr,doublepr,doublephr)若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn:manager(nn,id,gr,pr),technician(nn,id,gr,phr),employee(nn,id,gr){}voiddevelopermanager::pay(){intdays;cout<<"请输入请假天数:n";cin>>days;cout<<"请输入业绩系数:n";cin>>factor;cout<<"请输入研究进度系数:n";cin>>shfactor;hours=8*(23-days);base_salary=Grades[grade]*(23-days)/23;//基本工资career_salary=perhour*hours*shfactor*(23-days)/23;//技术人员奖金career_salary+=prize*factor*(23-days)/23;//加经理业绩工资career_salary/=2;salary=base_salary+career_salary;}classsalesmanager:publicmanager,publicsalesman{public:salesmanager(string=NULL,int=0,int=0,doublepr=0,doubleslfac=0);voidpay();};salesmanager::salesmanager(stringnn,intid,intgr,doublepr,doubleslfac):manager(nn,id,gr,pr),salesman(nn,id,gr,slfac),employee(nn,id,gr){}voidsalesmanager::pay(){intdays;cout<<"请输入请假天数:n";cin>>days;cout<<"请输入业绩系数:n";cin>>factor;课后答案网cout<<"请输入销售额:n";cin>>amount;www.hackshp.cnbase_salary=Grades[grade]*(23-days)/23;//基本工资career_salary=prize*factor*(23-days)/23;//经理业绩工资career_salary/=2;career_salary+=amount*slfactor;//加销售业绩工资salary=base_salary+career_salary;}intmain(){employeeeml1("张伟",10012,0),*emlp;managermag1("姚婕",20005,4,1000);techniciantec1("王茜",30047,5,10);salesmansal1("朱明",40038,2,0.05);developermanagerdem1("沈俊",50069,6,1500,12);salesmanagersam1("况钟",60007,3,1000,0.05);若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cneml1.pay();eml1.show();mag1.pay();mag1.show();tec1.pay();tec1.show();sal1.pay();sal1.show();emlp=&dem1;emlp->pay();emlp->show();emlp=&sam1;emlp->pay();emlp->show();return0;}8.7为上题添加拷贝构造函数,并测试是否正确。解:#include#includeusingnamespacestd;staticintGrades[]={500,600,750,1000,1400,2000,2800,4000};classemployee{protected:stringname;//姓名intID;//职工号intgrade;//工资级别doublesalary;课后答案网//月doublebase_salary;//基本月薪doublecareer_salary;//www.hackshp.cn业绩工资public:employee(string="",int=0,int=0);employee(employee&);//拷贝构造函数virtualvoidpay();//月薪计算函数voidshow();doublegetsalary(){returnsalary;}doublegetbase_salary(){returnbase_salary;}doublegetcareer_salary(){returncareer_salary;}};employee::employee(stringnn,intid,intgr){name=nn;ID=id;grade=gr;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnsalary=0;//月薪base_salary=0;//基本月薪career_salary=0;//业绩工资}employee::employee(employee&emp){//拷贝构造函数name=emp.name;ID=emp.ID;grade=emp.grade;salary=emp.salary;//月薪base_salary=emp.base_salary;//基本月薪career_salary=emp.career_salary;//业绩工资}voidemployee::show(){cout<>days;base_salary=Grades[grade]*(23-days)/23;career_salary=base_salary/2;//普通员工业绩工资为基本工资的一半salary=base_salary+career_salary;}classmanager:virtualpublicemployee{//虚基类protected:doubleprize;//固定奖金额doublefactor;//业绩系数public:manager(string="",课后答案网int=0,int=0,double=0);manager(manager&mag);//拷贝构造函数voidpay();www.hackshp.cn};manager::manager(manager&mag):employee(mag){//按赋值兼容规则mag可为employee的实参prize=mag.prize;factor=mag.factor;}manager::manager(stringnn,intid,intgr,doublepr):employee(nn,id,gr){prize=pr;//固定奖金额factor=0;}voidmanager::pay(){intdays;cout<<"请输入请假天数:n";若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncin>>days;cout<<"请输入业绩系数:n";cin>>factor;base_salary=Grades[grade]*(23-days)/23;career_salary=prize*factor*(23-days)/23;salary=base_salary+career_salary;}classtechnician:virtualpublicemployee{protected:doublehours;//月工作时数doubleperhour;//每小时附加酬金doubleshfactor;//研究进度系数public:technician(string="",int=0,int=0,double=0);technician(technician&);//拷贝构造函数voidpay();};technician::technician(technician&tech):employee(tech){//拷贝构造函数hours=tech.hours;//月工作时数perhour=tech.perhour;//每小时附加酬金shfactor=tech.shfactor;//研究进度系数}technician::technician(stringnn,intid,intgr,doublephr):employee(nn,id,gr){hours=0;perhour=phr;//每小时附加酬金shfactor=0;}voidtechnician::pay(){intdays;课后答案网cout<<"请输入请假天数:n";cin>>days;www.hackshp.cncout<<"请输入研究进度系数:n";hours=8*(23-days);cin>>shfactor;base_salary=Grades[grade]*(23-days)/23;career_salary=perhour*hours*shfactor*(23-days)/23;salary=base_salary+career_salary;}classsalesman:virtualpublicemployee{protected:doubleamount;//销售额doubleslfactor;//提成比例public:salesman(string="",int=0,int=0,double=0);若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnsalesman(salesman&);//拷贝构造函数voidpay();};salesman::salesman(stringnn,intid,intgr,doubleslfac):employee(nn,id,gr){amount=0;slfactor=slfac;//提成比例}salesman::salesman(salesman&sale):employee(sale){//拷贝构造函数amount=sale.amount;//销售额slfactor=sale.slfactor;//提成比例}voidsalesman::pay(){intdays;cout<<"请输入请假天数:n";cin>>days;cout<<"请输入销售额:n";cin>>amount;base_salary=Grades[grade]*(23-days)/23;career_salary=amount*slfactor;salary=base_salary+career_salary;}classdevelopermanager:publicmanager,publictechnician{public:developermanager(string="",intid=0,intgr=0,doublepr=0,doublephr=0);developermanager(developermanager&);//拷贝构造函数voidpay();};developermanager::developermanager(stringnn,intid,intgr,doublepr,doublephr):manager(nn,id,gr,pr),technician(nn,id,gr,phr),employee(nn,id,gr){}课后答案网developermanager::developermanager(developermanager&deman):manager(deman),technician(deman),employee(deman){}www.hackshp.cn//拷贝构造函数voiddevelopermanager::pay(){intdays;cout<<"请输入请假天数:n";cin>>days;cout<<"请输入业绩系数:n";cin>>factor;cout<<"请输入研究进度系数:n";cin>>shfactor;hours=8*(23-days);base_salary=Grades[grade]*(23-days)/23;//基本工资career_salary=perhour*hours*shfactor*(23-days)/23;//技术人员奖金career_salary+=prize*factor*(23-days)/23;//加经理业绩工资career_salary/=2;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnsalary=base_salary+career_salary;}classsalesmanager:publicmanager,publicsalesman{public:salesmanager(string="",int=0,int=0,doublepr=0,doubleslfac=0);salesmanager(salesmanager&);//拷贝构造函数voidpay();};salesmanager::salesmanager(stringnn,intid,intgr,doublepr,doubleslfac):manager(nn,id,gr,pr),salesman(nn,id,gr,slfac),employee(nn,id,gr){}salesmanager::salesmanager(salesmanager&salman):manager(salman),salesman(salman),employee(salman){}//拷贝构造函数voidsalesmanager::pay(){intdays;cout<<"请输入请假天数:n";cin>>days;cout<<"请输入业绩系数:n";cin>>factor;cout<<"请输入销售额:n";cin>>amount;base_salary=Grades[grade]*(23-days)/23;//基本工资career_salary=prize*factor*(23-days)/23;//经理业绩工资career_salary/=2;career_salary+=amount*slfactor;//加销售业绩工资salary=base_salary+career_salary;}intmain(){employeeeml1("张伟",10012,0),*emlp;managermag1("课后答案网姚婕",20005,4,1000);techniciantec1("王茜",30047,5,10);salesmansal1("朱明",40038,2,0.05);www.hackshp.cndevelopermanagerdem1("沈俊",50069,6,1500,12);salesmanagersam1("况钟",60007,3,1000,0.05);eml1.pay();eml1.show();mag1.pay();mag1.show();tec1.pay();tec1.show();sal1.pay();sal1.show();emlp=&dem1;emlp->pay();emlp->show();若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnemlp=&sam1;emlp->pay();emlp->show();cout<show();emlp=&sam0;emlp->show();return0;}8.8采用纯虚函数实现多态性来建立通用的双向链表派生类。参考【例8.10】和【例7.7】。解://ep8_9.h#includeusingnamespacestd;//首先看结点组织,采用结点类加数据类classObject{//数据类为抽象类课后答案网public:Object(){}www.hackshp.cnvirtualbooloperator>(Object&)=0;//纯虚函数,参数必须为引用或指针virtualbooloperator!=(Object&)=0;//纯虚函数,参数必须为引用或指针virtualvoidPrint()=0;//纯虚函数virtual~Object(){}//析构函数可为虚函数,构造函数不行};classDblNode{Object*info;//数据域用指针指向数据类对象DblNode*llink,*rlink;//前驱(左链)、后继(右链)指针public:DblNode();//生成头结点的构造函数~DblNode();voidLinkinfo(Object*obj);friendclassDblList;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn//以DblList为友元类,DblList可直接访问DblNode的私有函数,与结构一样方便,但更安全};DblNode::DblNode(){info=NULL;llink=rlink=NULL;}DblNode::~DblNode(){cout<<"删除结点类"<<"t";deleteinfo;//释放数据域}voidDblNode::Linkinfo(Object*obj){info=obj;}//再定义双链表类,选择常用操作classDblList{DblNode*head,*current;public:DblList();//构造函数,生成头结点(空链表)~DblList();//析构函数voidMakeEmpty();//清空链表,只余表头结点voidInsertFront(DblNode*p);//可用来向前生成链表,在表头插入一个结点voidInsertRear(DblNode*p);//可用来向后生成链表,在表尾添加一个结点voidInsertOrder(DblNode*p);//按升序生成链表DblNode*CreatNode();//创建一个结点(孤立结点)DblNode*DeleteNode(DblNode*p);//删除指定结点voidPrintList();//打印链表的数据域intLength();//计算链表长度DblNode*Find(Object&obj);//搜索数据域与定值相同的结点,返回该结点的地址//其它操作};DblList::DblList(){//建立表头结点head=newDblNode();head->rlink=head->llink=head;课后答案网current=NULL;}www.hackshp.cnDblList::~DblList(){MakeEmpty();//清空链表cout<<"删除头结点:";deletehead;}voidDblList::MakeEmpty(){DblNode*tempP;while(head->rlink!=head){tempP=head->rlink;head->rlink=tempP->rlink;//把头结点后的第一个节点从链中脱离tempP->rlink->llink=head;//处理左指针deletetempP;//删除(释放)脱离下来的结点}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncurrent=NULL;//current指针恢复}voidDblList::InsertFront(DblNode*p){p->llink=head;//注意次序p->rlink=head->rlink;head->rlink->llink=p;head->rlink=p;//最后做}voidDblList::InsertRear(DblNode*p){p->rlink=head;//注意次序p->llink=head->llink;head->llink->rlink=p;head->llink=p;//最后做}voidDblList::InsertOrder(DblNode*p){if(head==head->llink){p->llink=head;//注意次序p->rlink=head->rlink;head->rlink->llink=p;head->rlink=p;//最后做}else{current=head->rlink;while(current!=head){if(*current->info>*p->info)break;//找第一个比插入结点大的结点current=current->rlink;}p->rlink=current;//注意次序p->llink=current->llink;课后答案网current->llink->rlink=p;current->llink=p;www.hackshp.cn//最后做}}DblNode*DblList::CreatNode(){//建立新节点current=newDblNode();returncurrent;}DblNode*DblList::DeleteNode(DblNode*p){current=head->rlink;while(current!=head&¤t!=p)current=current->rlink;if(current==head)current=NULL;else{//结点摘下p->llink->rlink=p->rlink;p->rlink->llink=p->llink;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnp->rlink=p->llink=NULL;}returncurrent;}DblNode*DblList::Find(Object&obj){//对抽象类只能用“引用”current=head->rlink;while(current!=head&&*current->info!=obj)current=current->rlink;if(current==head)current=NULL;returncurrent;//搜索成功返回该结点地址,不成功返回NULL}voidDblList::PrintList(){current=head->rlink;while(current!=head){current->info->Print();current=current->rlink;}cout<rlink;while(current!=head){count++;current=current->rlink;}returncount;}//ep8_9.cpp#include"ep8_9.h"课后答案网#includeusingnamespacestd;www.hackshp.cnclassStringObject:publicObject{stringsptr;public:StringObject();StringObject(string);~StringObject();boolStringObject::operator>(Object&obj);//虚函数boolStringObject::operator!=(Object&obj);//虚函数voidPrint();};StringObject::StringObject(){sptr="";}StringObject::StringObject(strings){sptr=s;}StringObject::~StringObject(){cout<<"删除字符串类"<(Object&obj){//虚函数StringObject&temp=(StringObject&)obj;//必须转换returnsptr>temp.sptr;}boolStringObject::operator!=(Object&obj){//虚函数StringObject&temp=(StringObject&)obj;//必须转换returnsptr!=temp.sptr;}voidStringObject::Print(){cout<Linkinfo(p);//数据对象连接到结点list1.InsertFront(P1);//向前生成list1p=newStringObject(a[i]);P1=list2.CreatNode();P1->Linkinfo(p);list2.InsertRear(P1);//向后生成list2}list1.PrintList();cout<<"list1长度:"<Linkinfo(p);list3.InsertOrder(P1);//升序创建list3}list3.PrintList();cout<<"程序结束:"<课后答案网#includeusingnamespacestd;www.hackshp.cnclassBase{protected:doubleresult,a,b,step;//Intevalue积分值,a积分下限,b积分上限intn;public:virtualdoublefun(doublex)=0;//被积函数声明为纯虚函数virtualvoidIntegerate(){cout<<"这里是积分函数"<Integerate();//动态,可以访问派生类定义的被积函数bp->Print();sinLsl(0.0,3.1415926535/2.0,100);bp=&sl;bp->Integerate();//动态,可以访问派生类定义的被积函数bp->Print();sinSss(0.0,3.1415926535/2.0,100);bp=&ss;bp->Integerate();//动态,在层次中选bp->Print();expRer(0.0,1.0,100);bp=&er;bp->Integerate();//动态,可以访问派生类定义的被积函数bp->Print();expLel(0.0,1.0,100);bp=⪙bp->Integerate();//动态,可以访问派生类定义的被积函数bp->Print();expSes(0.0,1.0,100);bp=&es;bp->Integerate();//动态,在层次中选bp->Print();otherRor(0.0,1.0,100);bp=∨bp->Integerate();//动态,可以访问派生类定义的被积函数bp->Print();课后答案网otherLol(0.0,1.0,100);//增加到100000也达不到辛普生法的精度bp=&ol;www.hackshp.cnbp->Integerate();//动态,可以访问派生类定义的被积函数bp->Print();otherSos(0.0,1.0,100);bp=&os;bp->Integerate();//动态,在层次中选bp->Print();return0;}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn当前位置:学习资源下载>课后习题答案第九章流类库和输入/输出习题一.本概念与基础知识测试题9.19.1填空题9.1.1在C++中“流”是表示(1)。从流中取得数据称为(2),用符号(3)表示;向流中添加数据称为(4),用符号(5)表示。答案:(1)数据从一个对象到另一个对象的传送(2)提取操作(3)>>(4)插入操作(5)<<9.1.2抽象类模板(1)是所有基本流类的基类,它有一个保护访问限制的指针指向类(2),其作用是管理一个流的(3)。C++流类库定义的cin,cout,cerr和clog是(4)。cin通过重载(5)执行输入,而cout,cerr和clog通过(6)执行输出。答案:(1)basic_ios(2)basic_streambuf(3)缓冲区(4)全局流对象(5)>>(stream_extractionoperator)(6)<<(stream_insertionoperator)9.1.3C++在类ios中定义了输入输出格式控制符,它是一个(1)。该类型中的每一个量对应两个字节数据的一位,每一个位代表一种控制,如要取多种控制时可用(2)运算符来合成,放在一个(3)访问限制的(4)数中。所以这些格式控制符必须通过类ios的(5)来访问。答案:(1)公有的无名的枚举类型(2)或“|”课后答案网(3)保护(4)一个长整型数www.hackshp.cn(5)公共接口(函数)9.1.4取代麻烦的流格式控制成员函数,可采用(1),其中有参数的,必须要求包含(2)头文件。答案:(1)流操作子(2)iomanip9.1.5通常标准设备输入指(1)。标准设备输出指(2)。答案:(1)键盘(2)显示屏9.1.6EOF为(1)标志,在iostream.h中定义EOF为(2),在intget()函数中读入表明输入流结束标志(3),函数返回(4)。若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn答案:(1)文件结束标志(2)-1(3)^Z(Ctrl-Z)(4)EOF9.1.7C++根据文件内容的(1)可分为两类(2)和(3),前者存取的最小信息单位为(4),后者为(5)。答案:(1)数据格式(2)文本文件(3)二进制文件(4)字符(5)字节9.1.8当系统需要读入数据时是从(1)文件读入,即(2)操作。而系统要写数据时,是写到(3)文件中,即(4)操作。答案:(1)输入(2)提取(3)输出(4)插入9.1.9在面向对象的程序设计中,C++数据存入文件称作(1),而由文件获得数据称作(2)。按常规前者往往放在(3)函数中,而后者放在(4)函数中。答案:(1)把对象存入文件(2)由文件重构对象(3)析构函数(4)构造函数9.1.10文件的读写可以是随机的,意思是(1),也可以是顺序的,意思是(2)或(3)。答案:(1)可以从文件任何位置进行读写课后答案网(2)从文件头开始(3)从尾部续上www.hackshp.cn9.1.11C++把每一个文件都看成一个(1)流,并以(2)结束。对文件读写实际上受到(3)指针的控制,输入流的指针也称为(4),每一次提取从该指针所指位置开始。输出流的指针也称为(5),每一次插入也从该指针所指位置开始。每次操作后自动将指针向文件尾移动。如果能任意向前向后移动该指针,则可实现(6)。答案:(1)有序的字节(2)文件结束符(endoffilemarker)(3)文件定位(4)读指针(5)写指针(6)随机读写9.29.2简答题若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn9.2.1因cin为缓冲流,当键盘一次输入数据过多,保存在缓冲区中了,但这些数据可能是错的,希望清空它,以便下一次要求输入时,按提示正确输入,应该怎样办?答:只能读空缓冲区。9.2.2流状态标志字state各位代表了什么?怎样使用?答:全0,goodbit=0x00,流正常第1位为1,eofbit=0x01,输入流结束,忽略后继提取操作;或文件结束,已无数据可取第2位为1,failbit=0x02,最近的I/O操作失败,流可恢复第3位为1,badbit=0x04,最近的I/O操作非法,流可恢复第4位为1,hardfail=0x08,I/O出现致命错误,流不可恢复,VC++6.0不支持采用成员函数进行操作:intios::rdstate()const{returnstate;}//读取状态字intios:operator!()const{returnstate&(badbit|failbit);}//可用操作符!()代替fail()intios::bad(){returnstate&badbit;}//返回非法操作位voidios::clear(int_i){lock();state=_i;unlock();}//人工设置状态,可用来清状态intios::eof()const{returnstate&eofbit;}//返回流(文件)结束位intios::fail()const{returnstate&(badbit|failbit);}//返回操作非法和操作失败这两位intios::good()const{returnstate==0;}//正常返回1,否则返回09.2.3为什么cin输入时,空格和回车无法读入?这时可改用哪些流成员函数?答:因为空格和回车都可以作为数据之间的分格符,当输入串时空格和回车无法读入。可改用cin.get()和cin.getline()等流成员函数。9.2.4在用cin输入结束时键入^Z,则程序对以后的输入怎样处理?如果要求恢复正常,应执行什么成员函数?答:不再理会以后的所有输入。可执行成员函数:cin.clear(0);使流恢复正常9.2.5当输出字符串数组名时,输出的是串内容,有何办法可以输出串的首地址?答:将字符指针强制转换为泛型指针可以输出字符串地址课后答案网9.2.6文件的使用,有它的固定格式,请做简单介绍。www.hackshp.cn答:1.说明一个文件流对象,又被称为内部文件,如:fstreamiofile;2.用文件流对象的成员函数打开一个磁盘文件。打开文件的成员函数的第一个参数为要打开的磁盘文件名。第二个参数为打开方式,有输入(in),输出(out)等,打开方式在ios基类中定义为枚举类型。如:iofile.open(“myfile.txt”,ios::in|ios::out);1,2两步可合成如下:fstreamiofile(”myfile.txt”,ios::in|ios::out);3.使用提取和插入运算符对文件进行读写操作,或使用成员函数进行读写。4.关闭文件。当打开一个文件进行读写后,应该显式地关闭该文件如:iofile.close();若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn9.2.7在ios类中定义的文件打开方式中,公有枚举类型open_mode的各成员代表什么文件打开方式?答:in=0x01,//打开文件用于输入操作(从文件读取),如文件不存在则返回失败out=0x02,//打开文件用于输出操作(写入文件)(缺省方式)//如文件存在,未同时设app,ate,in则文件清空ate=0x04,//打开文件用于输入/输出,文件指针在文件尾,但新数据可写到任何位置app=0x08,//打开文件用于输出,但从尾部添加,新数据只能添加在尾部trunce=0x10,//打开文件,并清空它,不存在则建立新文件binary=0x80//以二进制方式打开文件9.2.8文本文件可以按行也可以按字符进行拷贝,在使用中为保证完整地拷贝各要注意哪些问题?答:按字符进行拷贝首先必须设置关闭跳过空白(如:iofile.unsetf(ios::skipws)),因为提取(“>>”)运算符在缺省情况下是跳过空白(包括空格,制表,backspace和回车等)的,这样拷贝的文件会缺少一些字符。第二,该程序应能确定文件是否拷贝结束。按行进行拷贝,getline()回车换行符并不放在buf中,因此要加一个回车换行符。9.2.9对文件流,“!”运算符完成什么功能?答:返回状态字state操作非法和操作失败这两位。9.2.10二进制文件读函数read()能否知道文件是否结束?应怎样判断文件结束?答:读函数并不能知道文件是否结束,可用状态函数intios::eof()来判断文件是否结束。必须指出系统是根据当前操作的实际情况设置状态位,如需根据状态位来判断下一步的操作,必须在一次操作后立即去调取状态位,以判断本次操作是否有效。9.2.11由二进制文件和文本文件来保存对象各有什么优点和缺点?答:使用二进制文件,可以控制字节长度,读写数据时不会出现二义性,可靠性高。同时不知格式是无法读取的,保密性好。文件结束后,系统不会再读(见课后答案网eofbit的说明),但程序不会自动停下来,所以要判断文件中是否已没有数据。使用文本文件来保存对象,操作简单,但谁都可以读取这些数据,无保密性。www.hackshp.cn9.2.12文件的随机访问为什么总是用二进制文件,而不用文本文件?答:在C++中可以由程序来实现文件指针的移动,从而实现文件的随机访问,即可读写流中任意一段内容。一般文本文件很难准确定位,所以随机访问多用于二进制文件。9.2.13怎样使用istream和ostream的成员函数来实现随机访问文件?答:在ios类中说明了一个公有枚举类型:enumseek_dir{beg=0,//文件开头cur=1,//文件指针的当前位置end=2//文件结尾};istream类中提供了如下三个成员函数:若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnistream&istream::seekg(streampos);//指针直接定位istream&istream::seekg(streamoff,ios::seek_dir);//指针相对定位longistream::tellg();//返回当前指针位置seekg(streamoff,ios::seek_dir)应用最广,如:datafile.seekg(-20L,ios::cur);表示将文件定位指针从当前位置向文件头部方向移20个字节。datafile.seekg(20L,ios::beg);表示将文件定位指针从文件头向文件尾方向移20个字节。datafile.seekg(-20L,ios::end);表示将文件定位指针从文件尾向文件头方向移20个字节。tellg()和seekg()往往配合使用。ostream类也提供了三个成员函数管理文件定位指针,它们是:ostream&ostream::seekp(streampos);ostream&ostream::seekp(streamoff,ios::seek_dir);longostream::tellp();定位指针只有一个但函数有两组,这两组个函数功能完全一样。二.编程与综合练习题9.3编程实现以下数据输入输出:a)以左对齐方式输出整数,域宽为12;b)以八进制、十进制、十六进制输入输出整数;c)实现浮点数的指数格式和定点格式的输入输出,并指定精度;d)把字符串读入字符型数组变量中,从键盘输入,要求输入串的空格也全部读入,以回车换行符结束;e)以上要求用流成员函数和流操作子各做一遍。解:特别注意flags()和setf()的使用方法。注意注释。#include#includeusingnamespacestd;课后答案网intmain(void){intinum1=255,inum2=8191,inum3=65535;www.hackshp.cndoublefnum=31.415926535,fnum1;charstr[255];cout<<"以左对齐方式输出整数,域宽为12:"<>fnum1;//输入3.1415926535cout<usingnamespacestd;intmain(void){charch,str[255];do{cout<<"请输入一个字符串:"<>ch;cin.get();//吸收输入YorN时留下的回车}while(!(ch=="Y"||ch=="y"));cout<<"输入正确:"<>”运算符。#include#include#include#includeusingnamespacestd;classstudent{intid;//学号stringname;//姓名charsex;//性别intage;//年龄stringaddress;//家庭地址floateng,phy,math,electron;//英语,物理,数学和电子学成绩public:student(int=0,string="#",char="#",int=0,string="#",float=0,float=0,float=0,float=0);friendostream&operator<<(ostream&dist,student&st);//重载插入运算符friendistream&operator>>(istream&sour,student&st);//重载提取运算符};//流类作为形式参数必须是引用student::student(inti,stringn,chars,inta,stringadd,floaten,floatph,floatma,floatele){id=i;name=n;课后答案网sex=s;age=a;www.hackshp.cnaddress=add;eng=en;phy=ph;math=ma;electron=ele;}ostream&operator<<(ostream&dist,student&st){//重载插入运算符dist<>(istream&sour,student&st){//重载提取运算符cout<<"请输入学号:"<>st.id;cout<<"请输入姓名:"<>st.name;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncout<<"请输入性别:"<>st.sex;cout<<"请输入年龄:"<>st.age;cout<<"请输入地址:"<>st.address;cout<<"请输入英语、物理、数学、电子各科成绩:"<>st.eng>>st.phy>>st.math>>st.electron;returnsour;}intmain(){studentst1,st2(2104105,"陈英","m",19,"黄山路380号",89,78,90,96);cin>>st1;cout<>”运算符,对所有可能的错误都能要求重输。解:#includeusingnamespacestd;classComplex{doubleReal,Image;public:Complex(doubler=0.0,doublei=0.0):Real(r),Image(i){};//定义构造函数//见【例5.7】,这里省略,以节约篇幅friendostream&operator<<(ostream&s,constComplex&z);friendistream&operator>>(istream&s,Complex&a);};//流类作为形式参数必须是引用课后答案网ostream&operator<<(ostream&s,constComplex&z){returns<<"("<>(istream&s,Complex&a){//格式为r;r,i;(r);(r,i);整个复数输完才可回车//容错强,如:sd(fr56cv,s79nml,45)i,78回车可正确判读为(56,79)doublere=0,im=0;charc=0;do{s>>c;}while(c!="("&&c!="."&&!(c>="0"&&c<="9"));//读空括号或数字前的无用字符if(c=="("){do{s>>c;}while(c!="."&&!(c>="0"&&c<="9"));//读空数字串前的无用字符s.putback(c);//返回一个字符到输入缓冲区若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cns>>re;//实部do{s.get(c);//因为可能是回车}while(c!="n"&&c!=")"&&c!=",");//读空数字串后的无用字符if(c==","){do{//只读数字串s>>c;}while(c!="."&&!(c>="0"&&c<="9"));s.putback(c);s>>im;//虚部do{s.get(c);//因为可能是回车}while(c!="n"&&c!=")");//读空数字串后的无用字符}elseim=0;//无此步,第二次赋值出错if(c!=")")s.clear(ios::failbit);//漏了括号给一个操作失败标志}else{s.putback(c);//无括号,返回一个字符到输入缓冲区s>>re;//实部do{s.get(c);//因为可能是回车}while(c!="n"&&c!=",");//读空数字串后的无用字符if(c==","){do{//只读数字串s>>c;}while(c!="."&&!(c>="0"&&c<="9"));s.putback(c);课后答案网s>>im;//虚部do{www.hackshp.cns.get(c);//因为可能是回车}while(c!="n");//读空数字串后的无用字符}elseim=0;//无此步,第二次赋值出错}if(s)a=Complex(re,im);returns;}intmain(){Complexa,b,c,d;cout<<"输入一个实数"<>a;cout<<"输入一个复数"<>b;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncout<<"输入一个用括号括起来的实数"<>c;cout<<"输入一个用括号括起来复数"<>d;cout<<"a="<#include//不包含#includeusingnamespacestd;intmain(){intline=0;charfilename[256],buf[256];fstreamsfile,dfile;cout<<"输入源文件路径名:"<>filename;//对路径各方面而言空格是无关紧要的,否则要用getline()等成员函数sfile.open(filename,ios::in);//打开一个已存在的文件while(!sfile){课后答案网cout<<"源文件找不到,请重新输入路径名:"<>filename;sfile.open(filename,ios::in);}cout<<"输入目标文件路径名:"<>filename;//只能创建文件,不能建立子目录,如路径不存在则失败dfile.open(filename,ios::out);if(!dfile){cout<<"目标文件创建失败"<#include#includeusingnamespacestd;intmain(){intn;charfilename[256],buf[100];fstreamsfile,dfile;cout<<"输入源文件路径名:"<>filename;//对路径各方面而言空格是无关紧要的,否则要用getline()等成员函数sfile.open(filename,ios::in|ios::binary);//打开一个已存在的二进制文件while(!sfile){课后答案网cout<<"源文件找不到,请重新输入路径名:"<>filename;sfile.open(filename,ios::in|ios::binary);}cout<<"输入目标文件路径名:"<>filename;//只能创建文件,不能建立子目录,如路径不存在则失败dfile.open(filename,ios::app|ios::out|ios::binary);//文件指针在尾部if(!dfile){cout<<"目标文件创建失败"<#include#includeusingnamespacestd;intmain(){intn;charfilename[256],buf[100];fstreamsfile,dfile;cout<<"输入源文件路径名:"<>filename;//对路径各方面而言空格是无关紧要的,否则要用getline()等成员函数sfile.open(filename,ios::in|ios::binary);//打开一个已存在的二进制文件while(!sfile){cout<<"源文件找不到,请重新输入路径名:"<>filename;sfile.open(filename,ios::in|ios::binary);}课后答案网cout<<"输入目标文件路径名:"<>filename;//只能创建文件,不能建立子目录,如路径不存在则失败dfile.open(filename,ios::in|ios::out|ios::binary);//打开输入输出文件if(!dfile){dfile.clear(0);dfile.open(filename,ios::out);//建立输出文件dfile.close();dfile.open(filename,ios::in|ios::out|ios::binary);//改为输入输出文件}dfile.seekp(0,ios::end);//写指针重定位到文件尾,seekp和seekg是同一个文件指针while(!sfile.eof()){//二进制方式需另判文件是否结束Asfile.read(buf,100);n=sfile.gcount();dfile.write(buf,n);//按实际读取字节数写若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}sfile.close();dfile.close();return0;}9.10采用筛选法求100以内的所有素数(参见【例3.16】)。将所得数据存入文本文件和二进制文件。对送入文本文件中的素数,要求存放格式是每行10个素数,每个数占6个字符,左对齐;可用任一文本编辑器将它打开阅读。二进制文件整型数的长度请用sizeof()来获得,要求可以正序读出,也可以逆序读出(利用文件定位指针移动实现),读出数据按文本文件中的格式输出显示。解:前半题文本文件与习题3.17相同,只是那里是右对齐,这里只新做了二进制文件。注意逆序输出前,试读看有多少数据时,一旦读到文件结束,eofbit=1,不清0,后面操作不能进行。#include#include#includeconstintn=100;voidmain(){ofstreamofile;ifstreamifile;inta[n],i,j;charch,b[256];for(i=0;i>ch;if(ch=="y"||ch=="Y"){ifile.open("myfile9_9.txt");i=0;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnwhile(ifile.get(b[i])){//读标题,不可用>>,它不能读白字符,if(b[i]=="n")break;i++;}b[i]="";cout.flags(ios::left);cout<>i;//由文件读入if(ifile.eof()!=0)break;cout<>ch;if(ch=="y"||ch=="Y"){count=0;ifile.open("myfile9_9.dat",ios::in|ios::binary);课后答案网while(1){ifile.read((www.hackshp.cnchar*)&i,sizeof(int));if(ifile.eof()!=0)break;cout<>ch;if(ch=="y"||ch=="Y"){count=0;ifile.open("myfile9_9.dat",ios::in|ios::binary);若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnwhile(1){ifile.read((char*)&i,sizeof(int));if(ifile.eof()!=0)break;count++;}ifile.clear(0);//当文件读完时,eofbit=1,不清0,后面的操作不能进行ifile.seekg(-4,ios::end);for(j=1;j<=count;j++){ifile.read((char*)&i,sizeof(int));cout<#include#include#includeusingnamespacestd;classsinx{课后答案网doubleDegree;//角度doubleValue;//正弦值www.hackshp.cnpublic:sinx(double=0);voiddisplay();voidBdatatofile(fstream&);//文件流类作为形式参数必须是引用voidBdatafromfile(fstream&);voiddatainput(doubledeg);booloperator<=(sinx&);booloperator==(sinx&);};boolsinx::operator<=(sinx&si){doublek;k=Degree-si.Degree;if(k<=0)returntrue;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnelsereturnfalse;}boolsinx::operator==(sinx&si){doublek;k=Degree-si.Degree;if(k==0)returntrue;elsereturnfalse;}sinx::sinx(doubledeg){Degree=deg;Value=sin(deg*3.1415926535/180);}voidsinx::display(){cout<classArray{T*elements;charname[20];www.hackshp.cnintSubscript;//已用最大下标值intmaxSize;fstreamdatafile;public:Array(char*="myfile",int=20);~Array();boolIsFull()const{returnSubscript==maxSize-1;}voidrenews();//数组扩大一倍voidordinsert(T&);//升序输入voidlistshow();//显示数组};templateArray::Array(char*filename,intmaxs){maxSize=maxs;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnSubscript=-1;//私有数据不容许直接赋初值,必须在构造函数中赋初值strcpy(name,filename);Ttemp;elements=newT[maxSize];datafile.open(name,ios::binary|ios::in);if(!datafile==0){while(!datafile.eof()){temp.Bdatafromfile(datafile);//datafile.read((char*)&temp,sizeof(T));//直接读写法与使用成员函数结果相同if(datafile.eof()==0){//读到无数据可读后,即读入不成功,eofbit为1ordinsert(temp);}}datafile.close();}datafile.clear(0);//采用标准库不可少,前面读到过文件结束或打开文件失败,无法恢复}templateArray::~Array(){inti;datafile.open(name,ios::binary|ios::out);for(i=0;i<=Subscript;i++)elements[i].Bdatatofile(datafile);//datafile.write((char*)&elements[i],sizeof(T));//直接读写法与使用成员函数结果相同datafile.close();delete[]elements;}课后答案网templatevoidArray::renews(){inti;www.hackshp.cnT*temp=elements;maxSize*=2;elements=newT[maxSize];for(i=0;i<=Subscript;i++)elements[i]=temp[i];delete[]temp;}templatevoidArray::ordinsert(T&elem){//以角度为关键字排序inti,j;if(IsFull())renews();for(i=0;i<=Subscript;i++)if(elem<=elements[i])break;if(!(elem==elements[i])){for(j=Subscript;j>=i;j--)elements[j+1]=elements[j];Subscript++;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}if(Subscript==-1)Subscript++;//考虑到进入的第一项elements[i]=elem;}templatevoidArray::listshow(){inti;for(i=0;i<=Subscript;i++)elements[i].display();}//两个文件归并用独立的函数模板templatevoidMerge(char*filename1,char*filename2,char*filename){fstreamsdatafile1(filename1,ios::out|ios::in|ios::binary);fstreamsdatafile2(filename2,ios::out|ios::in|ios::binary);fstreamddatafile(filename,ios::out|ios::binary);inti=0,j=0,k=0,ns1,ns2;Ttemps1,temps2;while(sdatafile1.eof()==0){//侧元素数量,注意会多出一个sdatafile1.read((char*)&temps1,sizeof(T));i++;}ns1=i-1;cout<<"表1元素数"<mylist("mydata1");cout<<"建立正弦表1(0,2,4,~80度)"<mylist("mydata2");cout<<"建立正弦表2(1,3,5,~81度;82,83,~90)"<("mydata1","mydata2","mydata");//按题意要求两个文件归并直接使用文件Arraymylist("mydata");cout<<"输出正弦表(0,1,~90度)"<#include#include#include课后答案网usingnamespacestd;classsinx{www.hackshp.cndoubleDegree;//角度doubleValue;//正弦值public:sinx(double=0);voiddisplay();voiddatainput(doubledeg);booloperator<=(sinx&);booloperator==(sinx&);};boolsinx::operator<=(sinx&si){doublek;k=Degree-si.Degree;if(k<=0)returntrue;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnelsereturnfalse;}boolsinx::operator==(sinx&si){doublek;k=Degree-si.Degree;if(k==0)returntrue;elsereturnfalse;}sinx::sinx(doubledeg){Degree=deg;Value=sin(deg*3.1415926535/180);}voidsinx::display(){cout<voidlistshow(T*elements,intsubsc){inti;for(i=0;i<=subsc;i++)elements[i].display();}templatevoidordinsert(T&elem,T*elements,intsubsc){//以角度为关键字排序inti,j;for(i=0;i<=subsc-1;i++)if(elem<=elements[i])break;if(!(elem==elements[i])){课后答案网for(j=subsc-1;j>=i;j--)elements[j+1]=elements[j];}www.hackshp.cnelements[i]=elem;}templateintreadfile(char*filename,T*elements){//文件写入链表,返回最大下标intk=-1;Ttemp;ifstreamdatafile;datafile.open(filename,ios::binary|ios::in);while(!datafile.eof()){datafile.read((char*)&temp,sizeof(T));if(datafile.eof()==0){//读到无数据可读后,即读入不成功,eofbit为1k++;ordinsert(temp,elements,k);}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}datafile.close();returnk;}templatevoidwritefile(char*filename,T*elements,intsubsc){inti;ofstreamdatafile;datafile.open(filename,ios::binary|ios::out);for(i=0;i<=subsc;i++)datafile.write((char*)&elements[i],sizeof(T));datafile.close();}//两个文件归并用独立的函数模板templatevoidMerge(char*filename1,char*filename2,char*filename){fstreamsdatafile1(filename1,ios::out|ios::in|ios::binary);fstreamsdatafile2(filename2,ios::out|ios::in|ios::binary);fstreamddatafile(filename,ios::out|ios::binary);inti=0,j=0,k=0,ns1,ns2;Ttemps1,temps2;while(sdatafile1.eof()==0){//求文件所含数据数量sdatafile1.read((char*)&temps1,sizeof(T));i++;}ns1=i-1;while(sdatafile2.eof()==0){sdatafile2.read((char*)&temps2,sizeof(T));j++;课后答案网}ns2=j-1;www.hackshp.cnsdatafile1.clear(0);sdatafile2.clear(0);i=0;j=0;sdatafile1.seekg(0,ios::beg);sdatafile2.seekg(0,ios::beg);sdatafile1.read((char*)&temps1,sizeof(T));//此方法与用成员函数完全相同sdatafile2.read((char*)&temps2,sizeof(T));//对于类对象,读和写及大小均仅指数据成员while(i("mydata1","mydata2","mydata");//按题意要求两个文件归并直接使用文件cout<<"输出正弦表(0,1,~90度)"<课后答案网#include#includewww.hackshp.cn#includeusingnamespacestd;classstudent{intid;//学号stringname;//姓名charsex;//性别intage;//年龄stringaddress;//家庭地址floateng,phy,math,electron;//英语,物理,数学和电子学成绩public:student(int=0,string="#",char="#",int=0,string="#",float=0,float=0,float=0,float=0);voidBdatatofile(fstream&dist);//数据写入文件流类voidBdatafromfile(fstream&sour);//由文件流类读出数据若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnbooloperator<=(student&ele){returnid<=ele.id;}booloperator==(student&ele){returnid==ele.id;}friendostream&operator<<(ostream&dist,student&st);//重载插入运算符friendistream&operator>>(istream&sour,student&st);//重载提取运算符};student::student(inti,stringn,chars,inta,stringadd,floaten,floatph,floatma,floatele){id=i;name=n;sex=s;age=a;address=add;eng=en;phy=ph;math=ma;electron=ele;}voidstudent::Bdatatofile(fstream&dist){//文件流类作为形式参数必须是引用dist.write((char*)&id,sizeof(int));dist.write(name.c_str(),20);//由string类的c_str()函数转为char*dist.write((char*)&sex,sizeof(char));dist.write((char*)&age,sizeof(int));dist.write(address.c_str(),20);//由string类的c_str()函数转为char*dist.write((char*)&eng,sizeof(float));dist.write((char*)&phy,sizeof(float));dist.write((char*)&math,sizeof(float));dist.write((char*)&electron,sizeof(float));}voidstudent::Bdatafromfile(fstream&sour){//文件流类作为形式参数必须是引用charDesc[20];sour.read((char*)&id,sizeof(int));sour.read(Desc,20);//必须由字符数组过渡name=Desc;课后答案网sour.read((char*)&sex,sizeof(char));sour.read((char*)&age,www.hackshp.cnsizeof(int));sour.read(Desc,20);//必须由字符数组过渡address=Desc;sour.read((char*)&eng,sizeof(float));sour.read((char*)&phy,sizeof(float));sour.read((char*)&math,sizeof(float));sour.read((char*)&electron,sizeof(float));}//由此可见读和写是完全对称的过程,次序决不能错ostream&operator<<(ostream&dist,student&st){//文件流类作为形式参数必须是引用dist<>(istream&sour,student&st){//文件流类作为形式参数必须是引用若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cncout<<"请输入学号:"<>st.id;cout<<"请输入姓名:"<>st.name;cout<<"请输入性别:"<>st.sex;cout<<"请输入年龄:"<>st.age;cout<<"请输入地址:"<>st.address;cout<<"请输入英语、物理、数学、电子各科成绩:"<>st.eng>>st.phy>>st.math>>st.electron;returnsour;}templateclassArray{T*elements;intSubscript;//已用最大下标值intmaxSize;fstreamdatafile;public:Array(int=3);//为了便于检验,缺省元素数暂为3~Array();boolIsFull()const{returnSubscript==maxSize-1;}voidrenews();//内存扩大一倍voidshow(){cout<<"已用最大下标值"<Array::Array(intmaxs){maxSize=maxs;Subscript=-1;//私有数据不容许直接赋初值,必须在构造函数中赋初值Ttemp;elements=newT[maxSize];datafile.open("mydatafile.dat",ios::binary|ios::in);//如文件不存在,打开失败if(!datafile==0){while(!datafile.eof()){temp.Bdatafromfile(datafile);if(datafile.eof()==0){//读到无数据可读后,即读入不成功,eofbit为1ordinsert(temp);//即使原文件未排序,退出时按排好序的重存}}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cndatafile.close();//必须放此处,打开成功才能关闭}datafile.clear(0);//前面曾经读到文件结束或文件打开失败,流无法恢复}templateArray::~Array(){inti;datafile.open("mydatafile.dat",ios::binary|ios::out);for(i=0;i<=Subscript;i++)elements[i].Bdatatofile(datafile);datafile.close();delete[]elements;}templatevoidArray::renews(){inti;T*temp=elements;maxSize*=2;elements=newT[maxSize];for(i=0;i<=Subscript;i++)elements[i]=temp[i];delete[]temp;}templatevoidArray::ordinsert(T&elem){//输入时以学号为关键字排序inti,j;if(IsFull())renews();for(i=0;i<=Subscript;i++)if(elem<=elements[i])break;if(!(elem==elements[i])){for(j=Subscript;j>=i;j--)elements[j+1]=elements[j];Subscript++;}elements[i]=elem;show();课后答案网}templateostream&www.hackshp.cnoperator<<(ostream&dist,Array&ar){inti;for(i=0;i<=ar.Subscript;i++)cout<mylist;studenttemp;charch;cout<<"是否输入新学生信息?YorN"<>ch;while(ch=="Y"||ch=="y"){cin.get();//吸收回车cin>>temp;若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnmylist.ordinsert(temp);cout<<"是否继续输入?YorN"<>ch;}cout<课后习题答案第十章异常处理习题一.基本概念与基础知识自测题10.110.110.1填空题10.1.1C++程序将可能发生异常的程序块放在(1)中,紧跟其后可放置若干对应的(2),在前面所说的块中或块所调用的函数中应该有对应的(3),由它在不正常时抛出(4),如与某一条(5)类型相匹配,则执行该语句。该语句执行完后,如未退出程序,则执行(6)。如没有匹配的语句,则交C++标准库中的(7)处理。答案:(1)try块(2)catch子句(3)throw表达式(4)异常(5)catch子句(6)后面的一条语句(7)terminate()10.1.2throw表达式的行为有点像函数的(1),而catch子句有点像函数的(2)。函数的调用和异常处理的主要区别在于:建立函数调用所需的信息在(课后答案网3)时已经获得,而异常处理机制要求(4)时的支撑。对于函数,编译器知道在哪个调用点上函数被真正调用,而对异常处理,异常是(www.hackshp.cn5)发生的,并沿(6)查找异常处理子句,这与(7)多态是(8)。答案:(1)调用(2)定义(3)编译(4)运行(5)随机(6)调用链逆向(7)运行时的(8)不一样的10.1.3异常也适用类的层次结构,与虚函数的规则(1),基类的异常(2)派生类异常catch子句处理,而反过来则(3)。答案:(1)相反若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn(2)不能被(3)能处理10.1.4异常处理时与函数重载(1),异常处理是由(2)catch子句处理,而不是由(3)catch子句处理,所以catch子句(4)是很重要的。答案:(1)解析不同(2)最先匹配到的(3)最佳匹配的(4)排列次序10.210.210.2简答题10.2.1当在try块中抛出异常后,程序最后是否回到try块中,继续执行后面的语句?答:不会回到try块中。。10.2.2什么叫做栈展开(stackunwinding)?异常在其中按怎样的步骤寻求处理?答:因发生异常而逐步退出复合语句和函数定义,被称为栈展开(stackstacstackstackunwindingkunwunwindinginding)。栈展开才是异常处理的核心技术。寻找匹配的catch子句有固定的过程:如果throw表达式位于try块中,则检查与try块相关联的catch子句列表,看是否有一个子句能够处理该异常,如果有匹配的,则该异常被处理;如果找不到匹配的catch子句,则在主调函数中继续查找。如果一个函数调用在退出时带有一个被抛出的异常未能处理,而且这个调用位于一个try块中,则检查与该try块相关联的catch子句列表,看是否有一个子句匹配,如果有,则处理该异常;如果没有,则查找过程在该函数的主调函数中继续进行。即这个查找过程逆着嵌套的函数调用链向上继续,直到找到处理该异常的catch子句。只要遇到第一个匹配的catch子句,就会进入该catch子句,进行处理,查找过程结束。10.2.3为什么C++要求资源的取得最好放在构造函数中,而资源的释放在析构函数中?答:退出调用链时必须释放所有资源。随着栈展开,在退出的复合语句和函数定义中声明的局部变量的生命期也结束了。在栈中分配的局部量占用的资源也被释放,由系统回收。但是课后答案网如果函数动态获得过资源(包括用new运算符取得的资源和打开的文件),因异常,这些资源的释放语句可能被忽略,则这些资源将永远不会被自动释放。www.hackshp.cn在栈展开期间,当一个复合语句(或语句块)或函数退出时,在退出的域中有某个局部量是类对象,栈展开过程将自动调用该对象的析构函数,完成资源的释放。所以C++异常处理过程本质上反映的是“资源获取是由构造函数实现,而资源释放是由析构函数完成”这样一种程序设计技术。10.2.1为什么要有异常重新抛出?异常重新抛出与处理的次序及过程是怎样的?答:当catch语句捕获一个异常后,可能不能完全处理异常,在完成某些操作后,catch子句可能决定该异常必须由函数链中更上级的函数来处理,这时catch子句可以重新抛出(rethrow)该异常,把异常传递给函数调用链中更上级的另一个catch子句,由它进行进一步处理。rethrow表达式仍为:throw;但仅有一个关键字,因为异常类型在catch语句中已经有了,不必再指明。被重新抛出的异常就是原来的异常对象。但是重新抛出异常的catch子句总是做了些工作,也应该把自己做若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn过的工作告诉下一个处理异常的catch子句,所以往往要对异常对象做一定修改,以表达某些信息,这时catch子句中的异常声明必须被声明为引用(参见上节),这样修改才能真正在异常对象自身中,而不是在拷贝中进行。10.2.2什么是异常规范?答:异常规范(exceptionspecification)提供了一种方案,可以随着函数声明列出该函数可能抛出的异常,并保证该函数不会抛出任何其他类型的异常。10.2.3当异常被组织成类层次结构时,对应catch子句应怎样排列?为什么?答:在处理类类型异常时,catch子句的排列顺序是非常重要的。当异常被组织成类层次结构时,类类型的异常可以被该类类型的公有基类的catch子句捕获到。为了保证异常的处理由最合适的catch子句来处理,派生类类型的catch子句必须先出现,以确保只有在没有其他catch子句适用时,才会进入基类类型的catch子句。10.2.4简述C++标准库的异常类层次结构。答:C++标准库中的异常层次的根类被称为exception,定义在库的头文件中,它是C++标准库函数抛出的所有异常类的基类。C++标准库还提供了一些类,可用在用户编写的程序中,以报告程序的不正常情况。这些预定义的错误被分为两大类:逻辑错误(logicerror)和运行时错误(run_timeerror)。逻辑错误是那些由于程序的内部逻辑而导致的错误或者违反了类的不变性的错误。逻辑异常包括:invalid_argment异常,如果函数接收到一个无效的实参,就会抛出该异常。out_of_range异常,如果函数接收到一个不在预期范围中的实参,则抛出该异常。length_error异常,用以报告企图产生一个“长度值超出最大允许值”的对象。domain_error异常,用以报告域错误(domainerror)。与此相对,运行时刻错误是由于程序域之外的事件而引起的错误。运行时刻错误只在程序执行时才是可检测的。运行时异常包括:range_error异常,报告内部计算中的范围错误。课后答案网overflow_error异常,报告算术溢出错误。underflow_error异常,报告算术下溢错误。以上三个异常是由www.hackshp.cnruntime_error类派生的。bad_alloc异常。当new()操作符不能分配所要求的存储区时,会抛出该异常。它是由基类exception派生的。一.编程与综合练习题10.3利用C++标准库的异常类结构,为顺序栈【例7.6】添加异常处理机构。栈满时的处理是把栈空间加倍,原栈内容拷入之后,再压栈。解:未用利用C++标准库的异常类结构,可由学生自己替换。#includeusingnamespacestd;templateclasspushOnFull{T_value;public:pushOnFull(Ti){_value=i;}若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cnTvalue(){return_value;}voidprint(){cerr<<"栈满,"<classpopOnEmpty{public:voidprint(){cerr<<"栈已空,无法出栈"<classstackfail{public:voidprint(){cerr<<"栈空间无法加倍,请按任意键退出"<classStack{inttop;//栈顶指针(下标)T*elements;//动态建立的数值intmaxSize;//栈最大允纳的元素个数public:Stack(int=20);//栈如不指定大小,设为20元素~Stack(){delete[]elements;}voidPush(constT&data);//压栈TPop();//弹出,top--TGetElem(inti){returnelements[i];}//返回指定元素,top不变voidMakeEmpty(){top=-1;}//清空栈boolIsEmpty()const{returntop==-1;}//判栈空boolIsFull()const{returntop==maxSize-1;}//判栈满voidPrintStack();//输出栈内所有数据voidStackFull();};templateStack::Stack(课后答案网intmaxs){maxSize=maxs;top=-1;www.hackshp.cnelements=newT[maxSize];//建立栈空间}templatevoidStack::PrintStack(){for(inti=0;i<=top;i++)cout<voidStack::Push(constT&data){if(IsFull())throwpushOnFull(data);//栈满则抛出异常elements[++top]=data;//栈顶指针先加1,元素再进栈,top是指向栈顶元素}templateTStack::Pop(){if(IsEmpty())throwpopOnEmpty();//栈已空则不能退栈,抛出异常returnelements[top--];//返回栈顶元素,同时栈顶指针退1若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cn}templatevoidStack::StackFull(){//堆栈加倍T*el=elements;inti=maxSize,j;maxSize*=2;//加倍栈空间if(maxSize<=32)elements=newT[maxSize];//条件语句是为了演示分配不成功elseelements=NULL;if(elements==NULL)throwstackfail();//分配不成功抛出异常for(j=0;jistack(4);for(i=0;i<20;i++){try{istack.Push(a[i]);}//到a[4],a[8],a[16]时栈满,异常catch(pushOnFull&eObj){eObj.print();try{istack.StackFull();}catch(stackfail&eObj){eObj.print();cin.get();return-1;}istack.Push(eObj.value());}}istack.PrintStack();课后答案网cout<<"数据出栈:"<&eObj){eObj.print();}try{for(i=0;i<41;i++){istack.Push(a[i%20]);cout<&eObj){eObj.print();若侵犯了您的版权利益,敬请来信告知!www.hackshp.cn 课后答案网:www.hackshp.cntry{istack.StackFull();}catch(stackfail&eObj){eObj.print();cin.get();return-1;}istack.Push(eObj.value());}return0;}10.4在【例8.9】中,当被积函数中出现被0除现象时,应抛出一个异常,但不退出主函数,可进行下一个定积分计算。解:利用C++标准库的异常类结构#include#include#include//采用C++标准库中的异常类#include#includeusingnamespacestd;constdoubleDefaultOverflow=1.0E10;classSimpson{doubleIntevalue,a,b;//Intevalue积分值,a积分下限,b积分上限public:virtualdoublefun(doublex)=0;//被积函数声明为纯虚函数Simpson(doublera=0,doublerb=0){a=ra;b=rb;课后答案网Intevalue=0;}www.hackshp.cnvoidIntegrate(){doubledx;inti;dx=(b-a)/2000;Intevalue=fun(a)+fun(b);for(i=1;i<2000;i+=2)Intevalue+=4*fun(a+dx*i);for(i=2;i<2000;i+=2)Intevalue+=2*fun(a+dx*i);Intevalue*=dx/3;}voidPrint(){cout<<"积分值="<Integrate();课后答案网s->Print();}//动态www.hackshp.cncatch(overflow_error&excp){cerr<

您可能关注的文档