• 396.00 KB
  • 2022-04-22 11:46:06 发布

《程序设计教程--用C++语言编程(第二版)》课后答案.doc

  • 102页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'21程序设计教程--用C++语言编程(第二版习题解答)目录第1章概述2第2章基本数据类型和表达式4第3章程序的流程控制――语句7第4章过程抽象――函数16第5章构造数据类型22第6章数据抽象――类37第7章操作符重载53第8章继承――派生类77第9章类属(泛型)机制――模板87第10章输入/输出(I/O)89第11章异常处理90第12章实例--面向对象的Windows应用程序框架90 21第1章概述1、简述冯•诺依曼计算机的工作模型。答:冯•诺依曼计算机的工作模型是:待执行的程序从外存装入到内存中,CPU从内存中逐条地取程序中的指令执行;程序执行中所需要的数据从内存或从外设中获得,程序执行中产生的中间结果保存在内存中,程序的执行结果通过外设输出。2、简述寄存器、内存以及外存的区别。答:寄存器主要用于记录下一条指令的内存地址、当前指令的执行状态以及暂时保存指令的计算结果供下一(几)条指令使用,其作用主要是减少访问内存的次数,提高指令的执行效率。内存用于存储计算机程序(指令和数据),内存由许多存储单元构成,每个存储单元都有一个地址,对存储单元的访问是通过其地址来进行的,与寄存器相比,内存的容量要大得多,但指令访问内存单元所花费的时间比访问寄存器要多得多。外存是大容量的低速存储部件,用于永久性地存储程序、数据以及各种文档等信息,存储在外存中的信息通常以文件形式进行组织和访问,外存储了在容量和速度上与内存不同,另一个区别在于内存中存储的是正在运行的程序和正在使用的数据,外存中存储的则是大量的、并非正在使用的程序和数据。3、CPU能执行哪些指令?答:CPU所能执行的指令通常有:算术指令:实现加、减、乘、除等运算。比较指令:比较两个操作数的大小。数据传输指令:实现CPU的寄存器、内存以及外设之间的数据传输。执行流程控制指令:用于确定下一条指令的内存地址,包括转移、循环以及子程序调用/返回等指令。4、什么是软件?软件是如何分类的?答:计算机软件是计算机系统中的程序以及有关的文档。程序是对计算任务的处理对象(数据)与处理规则(算法)的描述;文档是为了便于人理解程序所需的资料说明,供程序开发与维护使用。软件通常 21可以分为系统软件、支撑软件和应用软件。系统软件居于计算机系统中最靠近硬件的一级,它与具体的应用领域无关,其他软件一般要通过系统软件发挥作用,如操作系统属于系统软件。支撑软件是指支持软件开发与维护的软件,一般由软件开发人员使用,如软件开发环境就是典型的支撑软件。应用软件是指用于特定领域的专用软件,如人口普查软件、财务软件等。1、什么是虚拟机?答:在由硬件构成的计算机(称为“裸机”)之上,加上一些软件就得到了一个比它功能更强的计算机,称为“虚拟机”。2、十进制数0.1的二进制表示是什么?答:(0.1)10=(0.000110011...)2,它是无限循环小数。也就是说,十进制数0.1无法精确用二进制表示!3、简述程序设计范型。答:基于不同的计算模型来对计算进行描述就形成了不同的程序设计范型。典型的程序设计范型有:过程式、对象式、函数式以及逻辑式等。过程式程序设计是一种以功能为中心、基于功能分解和过程抽象的程序设计范型。一个过程式程序由一些子程序构成,每个子程序对应一个子功能,它实现了功能抽象。对象式程序设计是一种以数据为中心、基于数据抽象的程序设计范型。一个面向对象程序由一些对象构成,对象是由一些数据及可施于这些数据上的操作所组成的封装体。函数式程序设计是围绕函数来进行的,计算过程体现为一系列的函数应用。逻辑程序设计是把程序组织成一组事实和一组推理规则,在事实基础上运用推理规则来实施计算。4、简述程序设计的步骤。答:程序设计一般遵循以下步骤:明确问题;系统设计;用某种语言进行编程;测试与调试;运行与维护5、低级语言与高级语言的不同之处是什么?答:低级语言是指与特定计算机体系结构密切相关的程序语言,它是特定计算机能够直接理解的语言(或与之直接对应的语言),包括机器语言和汇编语言。低级语言的优点在于:写出的程序效率比较高,包括执行速度快和占用空间少。其缺点是:程序难以设计、理解与维护,难以保证程序的正确性。高级语言是指人容易理解和有利于人对解题过程进行描述的程序语言。高级语言的优点在于:程序容易设计、理解与维护,容易保证程序正确性。高级语言的缺点是:用其编写的程序相对于用低级语言编写的程序效率要低,翻译成的目标代码量较大。 211、简述编译与解释的区别。答:编译是指把高级语言程序首先翻译成功能上等价的机器语言程序或汇编语言程序,然后执行目标代码程序,在目标代码程序的执行中不再需要源程序。解释则是指对源程序中的语句进行逐条翻译并执行,翻译完了程序也就执行完了,这种翻译方式不产生目标程序。一般来说,编译执行比解释执行效率要高。2、简述C++程序的编译执行过程。在你的C++开发环境中运行1.3.2节中给出的简单C++程序。答:首先可以利用某个编辑程序把C++源程序输入到计算机中,并作为文件保存到外存中,文件名为“*.cpp”和“*.h”。然后利用某个C++编译程序对保存在外存中的C++源程序进行编译,编译结果作为目标文件保存到外存,文件名为“*.obj”。然后再通过一个联接程序把由源文件产生的目标文件以及程序中用到的一些系统功能所在的目标文件联接起来,作为一个可执行文件保存到外存,文件名为“*.exe”。最后通过操作系统提供的应用程序运行机制,把可执行文件装入内存,运行其中的可执行程序。在VisualC++6.0环境中,首先要建立一个project(项目);其次往该project中添加、编辑程序模块(源文件);然后选择菜单Build中的Build...或RebuildAll;最后选择菜单Build中的Execute...运行程序。3、C++的单词分成哪些种类?答:构成C++的单词有:标识符、关键词、字面常量、操作符以及标点符号等。4、下面哪一些是合法的C++标识符?extern,_book,Car,car_1,ca1r,1car,friend,car1_Car,Car_Type,No.1,123答:合法的C++标识符:_book,Car,car_1,ca1r,car1_Car,Car_Type第2章基本数据类型和表达式1、C++提供了哪些基本数据类型?检查你的计算机上各种类型数据所占内存空间的大小(字节数)。答:C++提供了以下5种基本数据类型:整数类型、实数类型、字符类型、逻辑类型以及空值类型。一台计算机上各种数据类型的数据所占用的内存大小(字节数)可以通过“sizeof(类型名)”来计算。2、下面哪一些是合法的C++字面常量,它们的类型是什么?-5.23,1e+50,-25,105,20.20,e5,1e-5,-0.0e5,"n" 21-000,"A","5","3.14",falsered,"r","f""TodayisMonday.","""答:字面常量是指在程序中直接写出常量值的常量。-5.23,1e+50,-25,20,.20,1e-5,-0.0e5,"n",-000,"A","5","r","f","TodayisMonday.","""都是字面常量。其中:整数类型常量:-25,20,-000实数类型常量:-5.23,1e+50,.20,1e-5,-0.0e5字符常量:"n","A","5","r","f"字符串常量:"TodayisMonday.","""1、什么是符号常量?符号常量的优点是什么?答:符号常量是指有名字的常量,在程序中通过常量的名字来使用这些常量。程序中使用符号常量有以下优点:1)增加程序易读性2)提高程序对常量使用的一致性3)增强程序的易维护性2、如何理解变量?变量定义和声明的作用是什么?答:在程序中,其值可以改变的量称为变量。变量可以用来表示可变的数据。程序中使用到的每个变量都要有定义。变量定义指出变量的类型和变量名,另外还可以为变量提供一个初值。C++中使用变量之前,必须对使用的变量进行声明(变量定义属于一种声明,即:定义性声明),变量声明指出了一个变量的类型,使得编译程序能对变量的操作进行类型检查并做相应的类型转换。整个程序中,某变量的定义只能由一个,但它的声明可以有多个。3、什么是表达式?其作用是什么?答:表达式是由操作符、操作数以及圆括号所组成的运算式。在程序设计语言中,对数据操作的具体实施是通过表达式来描述的。4、操作符的优先级和结合性分别是指的什么?答:运算符的优先级和结合性决定表达式中各个运算符的运算次序。操作符的优先级规定了相邻的两个操作符谁先运算:优先级高的先计算;如果相邻的两个操作符具有相同的优先级,则需根据操作符的结合性来决定先计算谁,操作符的结合性通常分为左结合和右结合:左结合表示从左到右计算,右结合表示从右到左计算。5、表达式中的类型转换规则是什么?下面的表达式计算时如何进行操作数类型转换?(1)3/5*12.3(2)"a"+10*5.2(3)12U+3.0F*24L答:表达式中类型转换规则是:基于单个操作符依次进行转换。1)3与5同类型,不转换,结果为0,转换成double型后与12.3做乘法。2)10转换成double型与5.2做乘法,’a’转换成double型后与前者结果做加法。 213)3.0F与24L均转换成double型后做乘法,12U转换成double型后与前者结果做加法。1、将下列公式表示成C++的表达式:(1)(可利用C++标准库中的求平方根的函数:sqrt(x))(2)(3)答:1)(-1*b+sqrt(b*b-4*a*c))/(2*a)2)sqrt(s*(s-a)*(s-b)*(s-c))3)((a*b)/(c*d))*(3/(1+(b/(2.5+c))))+(4*pi*r*r*r/3)2、写出下列条件的C++表达式(1)i能被j整除。(2)ch为字母字符。(3)m为偶数。(4)n是小于100的奇数。(5)a、b、c构成三角形的三条边。答:1)i%j==02)((ch>="a")&&(ch<="z"))||((ch>="A")&&(ch<="Z"))3)m%2==04)(n<100)&&(n%2!=0)5)(a>0)&&(b>0)&&(c>0)&&(a+b>c)&&(b+c>a)&&(c+a>b)或((a+b)>c)&&(abs(a-b)0)&&(b>0)&&(c>0)可以不用判断3、在你的计算机上运行下面的程序:#includeusingnamespacestd;intmain(){doublea=3.3,b=1.1;inti=a/b;cout<usingnamespacestd;intmain(){doublec,f;cout<<"PleaseinputanF-temperature:"<>f;c=(f-32)*5/9;cout<<"TheC-temperatureis:"< 21usingnamespacestd;intmain(){inthour,minute;charnoon;cout<<"Pleaseinputatimein24-hourformat:"<>hour;if(hour<0||hour>23){cout<<"Theinputhouriswrong!"<12){hour=hour-12;noon="p";}elsenoon="a";cout<<"minute:";cin>>minute;if(minute<0||minute>59){cout<<"Theinputminuteiswrong!"<usingnamespacestd;intmain(){charc;for(c="a";c<="z";c++)cout<="a";c--)cout<usingnamespacestd;intmain(){unsignedintgzint;intcount=0;while(1){cout<<"Pleaseinputaninteger(greaterthanzero):"<>gzint;if(gzint<=0)cout<<"Yourinputiswrong!Pleaseinputagain..."<usingnamespacestd;intmain(){intcount=0;charch;cout<<"Pleaseinputanexpression:"<>ch;ch!="#";cin>>ch){if(ch=="(")count++;elseif(ch==")") 21count--;}if(count==0)cout<<"配对!"<0)cout<<"多左括号!"<=”进行计数。解:#includeusingnamespacestd;intmain(){intcount=0;charch1="",ch2;cout<<"Pleaseinputastring(terminatedwith#):"<>ch2;ch2!="#";cin>>ch2){if(ch2=="="&&ch1==">")count++;ch1=ch2;}cout<<"Numberof>=:"<usingnamespacestd; 21intmain(){intcharge;doubleweight;cout<<"Pleaseinputtheweightofthepackage:"<>weight;if(weight<=0)cout<<"Theinputweightiswrong!"<>distance;if(distance<=0)cout<<"Theinputeddistanceiswrong!"<#includeusingnamespacestd;intmain() 21{doubleitem=1.0,sum=0.0;inti=1,sign=1;while(fabs(item)>=1e-8){sum+=item;sign*=-1;i+=2;item=sign/(double)i;}cout<usingnamespacestd;intmain(){for(intn=100;n<=999;n++){inti,j,k;i=n/100;//百位数字j=n%100/10;//十位数字k=n%10;//个位数字if(n==i*i*i+j*j*j+k*k*k)cout<usingnamespacestd;intmain(){for(inti=1;i<=9;i++){intn=i*100,m=i*i*i;for(intj=0;j<=9;j++){intn1=n+j*10,m1=m+j*j*j;for(intk=0;k<=9;k++){if(n1+k==m1+k*k*k)cout<usingnamespacestd;intmain(){inta,b;cout<<"Pleaseinputa,b:"<>a>>b;intc=(a>b)?b:a;while(c>0){if(a%c==0&&b%c==0)break;c--;}cout<usingnamespacestd;intmain(){inta,b;cout<<"Pleaseinputa,b:"<>a>>b;intc;do{c=a-b*(a/b);a=b;b=c;}while(c!=0);cout<usingnamespacestd;intmain(){for(inti=0;i<10;i++){if(i!=0)cout<b?a:b;for(inti=max;i>0;i--)if((a%i==0)&&(b%i==0))returni;}1、写出下面程序的执行结果:#includeusingnamespacestd;intcount=0;intfib(intn){count++;if(n==1||n==2)return1;elsereturnfib(n-1)+fib(n-2);}intmain(){cout<1)答:#include 21usingnamespacestd;doubleHermit_Iterative(int,double);//迭代方法doubleHermit_Recursion(int,double);//递归方法voidmain(){constintn=3;//n与x可自行指定doublex=3.14;cout<0,n>0)答:intAck(intm,intn){if(m==0)returnn+1;elseif(n==0)returnAck(m-1,1);elsereturnAck(m-1,Ack(m,n-1));} 211、根据下图写一个函数:intpath(intn);用于计算从结点1到结点n(n大于1)共有多少条不同的路径。24681357答:intpath(intn){if(n==1)return1;if(n==2)return1;if(n==3)return2;if(n%2==0)returnpath(n-1)+path(n-2)+path(n-3);elsereturnpath(n-1)+path(n-2);}2、编程解决下面的问题:若一头小母牛,从出生起第四个年头开始每年生一头母牛,按此规律,第n年有多少头母牛?答:除了第一年到第三年外,每一年的母牛数应该是上一年的母牛数加上三年前的母牛数(现在它们是第四年了,要生小牛了!)intf(intn){if(n==1||n==2||n==3)return1;returnf(n-3)+f(n-1);}3、假设有三个重载的函数:voidfunc(int,double);voidfunc(long,double);voidfunc(int,char);对下面的函数调用,指出它们分别调用了哪一个重载函数;如果有歧义,指出导致歧义的重载函数定义。func("c",3.0);func(3L,3);func("three",3.0);func(3L,"c");func(true,3);答:func("c",3.0);与voidfunc(int,double);匹配func(3L,3);与voidfunc(long,double);匹配func("three",3.0);没有与之匹配的函数func(3L,"c");与voidfunc(long,double);和voidfunc(int,char);均能匹配 21func(true,3);与voidfunc(int,double);和voidfunc(int,char);均能匹配1、下面的函数定义为什么是正确的?在函数f中如何区分(使用)它们?voidf(){intf;.......}答:两个f的作用域不一样,voidf()中的f为全局作用域,intf;中的f为局部作用域。在函数f中如果使用局部变量,则用f;如果使用函数f,则用::f。2、为什么一般把内联函数的定义放在个头文件中?答:为了防止同一个内联函数的各个定义之间的不一致,往往把内联函数的定义放在某个头文件中,在需要使用该内联函数的源文件中用文件包含命令#include把该头文件包含进来。由于内联函数名具有文件作用域,因此,不会出现重复定义问题。3、用循环实现Error!Referencesourcenotfound.中的辗转相除法计算最大公约数。 103答:intgcd(intx,inty){while(y!=0){intt=y;y=x%y;x=t;}returnx;}第5章构造数据类型1、枚举类型有什么好处?C++对枚举类型的操作有何规定?答:使用枚举类型有利于提高程序的易读性;使用枚举类型也有利于保证程序的正确性。首先,可以对枚举类型实施赋值操作,但不同枚举类型之间不能相互赋值,而且不能把一个整型数直接赋值给枚举类型的变量。还可以对枚举类型实施比较运算。还可以对枚举类型实施算术运算,对枚举类型的运算前要转换成对应的整型值,且运算结果类型为算术类型,而且不能对枚举类型的值直接进行输入/输出。2、指针类型主要用于什么场合?引用类型与指针类型相比,其优势在哪里?答:指针类型主要用于参数传递和对动态变量的访问。在C++中,指针类型还用于访问数组元素,以提高访问效率。引用类型与指针类型都可以实现通过一个变量访问另一个变量,但访问的语法形式不同:引用是采用直接访问形式,指针则采用间接访问形式。在作为函数参数类型时,引用类型参数的实参是一个变量,而指针类型参数的实参是一个变量的地址。除了在定义时指定的被引用变量外,引用类型变量不能再引用其他变量;而指针变量定义后可以指向其他同类型的变量。因此,引用类型比指针类型要安全。引用类型的间接访问对使用者而言是透明的。3、写出下面程序的运行结果:#includeusingnamespacestd;voidf(int&x,inty){y=x+y;x=y%3;cout<usingnamespacestd;enumDay{SUN,MON,TUE,WED,THU,FRI,SAT};intmain(){doublemax,min,maxsum=0,minsum=0;for(Dayd=SUN;d<=SAT;d=(Day)(d+1)){cout<<"Pleaseinput";switch(d){caseSUN:{cout<<"Sunday";break;}caseMON:{cout<<"Monday";break;}caseTUE:{cout<<"Tuesday";break;}caseWED:{cout<<"Wednesday";break;}caseTHU:{cout<<"Thursday";break;}caseFRI:{cout<<"Friday";break;}caseSAT:{cout<<"Saturday";break;}}cout<<""stemperature(maxmin):"<>max>>min;maxsum+=max;minsum+=min;}cout<<"Theaveragetemperatureofmaxismis:"<=0){x1=(sqrt(i)-b)/(2*a);x2=(0-sqrt(i)-b)/(2*a);return1;}else{x1=(0-b)/(2*a);x2=sqrt(0-i)/(2*a);return0;}}3、编写一个程序,从键盘输入一个字符串,分别统计其中的大写字母、小写字母以及数字的个数。 103解:#includeusingnamespacestd;intmain(){charstr[100];cout<<"Pleaseinputastring:n";cin>>str;intcount_lower=0,count_upper=0,count_num=0;for(inti=0;str[i]!="";i++){if(str[i]>="A"&&str[i]<="Z")count_upper++;elseif(str[i]>="a"&&str[i]<="z")count_lower++;elseif(str[i]>="0"&&str[i]<="9")count_num++;}cout<usingnamespacestd;#defineM3#defineN3intmain(){inta[M][N];//存放矩阵inti,j;//输入矩阵元素for(i=0;i>a[i][j];intlin_max[M],//存放各行的最大元素col_min[N];//存放各列的最小元素//计算每行的最大元素for(i=0;imax)max=a[i][j];lin_max[i]=max;}//计算每列的最小元素for(j=0;jusingnamespacestd;#defineN3inta[N][N];intmain(){inti,j;for(i=0;i*p2)return1;elseif(*p1<*p2)return-1;}if(*p1==""&&*p2=="") 103return0;elseif(*p1=="")return-1;elsereturn1;}intstrncmp2(constchars1[],constchars2[],intn){for(constchar*p1=s1,*p2=s2;n!=0&&*p1!=""&&*p2!="";p1++,p2++,n--){if(*p1>*p2)return1;elseif(*p1<*p2)return-1;}if(n==0||*p1==""&&*p2=="")return0;elseif(*p1=="")return-1;elsereturn1;}1、编写一个函数intsqueeze(chars1[],constchars2[]),它从字符串s1中删除所有在s2里出现的字符,函数返回删除的字符个数。解:intsqueeze(chars1[],constchars2[]){intcount=0,i=0;while(s1[i]!=""){for(intj=0;s2[j]!=""&&s1[i]!=s2[j];j++);if(s2[j]=="")i++;else{for(intk=i+1;s1[k]!="";k++)s1[k-1]=s1[k];s1[k-1]="";count++;}}returncount;}2、编写一个函数find_replace_str,其原型如下:intfind_replace_str(charstr[],constcharfind_str[],constcharreplace_str[]);要求:该函数能够完成把字符串str中的所有子串find_str都替换成字符串replace_str,返回值为替换的次数。解:voidfind_replace_str(charstr[],constcharfind_str[],constchar 103replace_str[]){intindex=0,//str中的当前处理位置     find_len=strlen(find_str),     replace_len=strlen(replace_str),     offset=find_len-replace_len;  while(strlen(str+index)>=find_len) {if(strncmp(str+index,find_str,find_len)==0)   {if(offset<0)//把字符串剩余部分往后移-offset个位置     { intn=strlen(str+index)-find_len+1;//剩余部分的字符个数+1("")       for(inti=strlen(str);n>0;i--,n--)        str[i+(-offset)]=str[i];     }     elseif(offset>0)//把字符串剩余部分往前移offset个位置     { intn=strlen(str+index)-find_len+1;//剩余部分的字符个数+1("")       for(inti=index+find_len;n>0;i++,n--)       str[i-offset]=str[i];     }     for(inti=0;iusingnamespacestd;structStudent{charid[11];charname[9];doublescores[9];};intmain(){intn;cout<<"请输入学生人数:";cin>>n;Student*students=newStudent[n];//创建动态数组以存放学生信息。//输入每个学生的信息。inti,j;for(i=0;i>students[i].id;cout<<"姓名:";cin>>students[i].name; 103cout<<"8门课成绩:";students[i].scores[8]=0.0;for(j=0;j<8;j++){cin>>students[i].scores[j];students[i].scores[8]+=students[i].scores[j];}students[i].scores[8]/=8;//平均成绩}//根据平均成绩对学生信息进行排序。for(i=n;i>1;i--){boolexchange=false;for(j=1;jstudents[j-1].scores[8]){Studenttemp=students[j];students[j]=students[j-1];students[j-1]=temp;exchange=true;}}if(!exchange)break;}//输出排序后的学生信息for(i=0;ivalue=a;q->next=h;h=q;returntrue;}else{Node*p=h;inti=1;while(p!=NULL&&inext;i++;}if(p!=NULL){q=newNode;q->value=a;q->next=p->next;p->next=q;returntrue;}elsereturnfalse;}}2、把在链表中删除一个结点的操作写成一个函数:boolremove(Node*&h,int&a,intpos); 103其中,h为表头指针,a用于存放删除的结点的值,pos(>0)表示删除结点的位置。操作成功返回true,否则返回false。解:structNode{intvalue;Node*next;};boolremove(Node*&h,int&a,intpos){Node*p=h,*q=NULL;inti=1;while(p!=NULL&&inext;i++;}if(p!=NULL){a=p->value;if(q!=NULL)q->next=p->next;elseh=p->next;deletep;returntrue;}elsereturnfalse;}1、编写一个程序,首先建立两个集合(从键盘输入集合的元素),然后计算这两个集合的交集、并集以及差集,最后输出计算结果。要求用链表实现集合的表示。解:#includeusingnamespacestd;structNode{intvalue;Node*next;};boolfind(Node*h,intx)//在h中查找x{for(Node*p=h;p!=NULL;p=p->next)if(p->value==x)returntrue;returnfalse;}voidinsert(Node*&h,intx)//在h中增加一个元素{Node*p=newNode;p->value=x;p->next=h;h=p;}Node*input()//建立集合{Node*h=NULL; 103intx;for(cin>>x;x!=-1;cin>>x){if(find(h,x))continue;insert(h,x);}returnh;}Node*set_union(Node*h1,Node*h2)//集合“并”{Node*h=NULL,*p;//生成一个与h1一样的集合hfor(p=h1;p!=NULL;p=p->next)insert(h,p->value);//把h2加入到h中(去重)for(p=h2;p!=NULL;p=p->next){if(!find(h1,p->value))insert(h,p->value);}returnh;}Node*set_intersection(Node*h1,Node*h2)//集合“交”{Node*h=NULL;for(Node*p=h1;p!=NULL;p=p->next){if(find(h2,p->value))insert(h,p->value);}for(Node*q=h2;q!=NULL;q=q->next){if(!find(h1,q->value))insert(h,q->value);}returnh;}Node*set_difference(Node*h1,Node*h2)//集合“差”{Node*h=NULL;for(Node*p=h1;p!=NULL;p=p->next){if(!find(h2,p->value))insert(h,p->value);}returnh;}voidoutput(Node*h)//输出集合的所有元素{for(Node*p=h;p!=NULL;p=p->next)cout<value<<"";cout<next;deletep;}}intmain(intargc,char*argv[]) 103{Node*set1,*set2,*set3,*set4,*set5;set1=input();set2=input();set3=set_union(set1,set2);set4=set_intersection(set1,set2);set5=set_difference(set1,set2);output(set1);output(set2);output(set3);output(set4);output(set5);remove(set1);remove(set2);remove(set3);remove(set4);remove(set5);return0;}1、在排序算法中,有一种排序算法(插入排序)是:把待排序的数分成两个部分:AB其中,A为已排好序的数,B为未排好序的数,初始状态下,A中只有一个元素。该算法依次从B中取数插入到A中的相应位置,直到B中的数取完为止。请在链表表示上实现上述的插入排序算法。解:structNode{intcontent;Node*next;};voidinsert_sort(Node*&h){if(h==NULL)return;Node*q=h->next;//q指向B部分的第一个元素h->next=NULL;//h指向A部分的第一个元素(初始状态下,A部分只有一个元素)while(q!=NULL)//对第二部分的元素进行循环{//从B部分取一个元素Node*q1=q;//q1指向取到的元素q=q->next;//从B中去掉一个元素//循环在A部分中从头开始找一个元素(p指向它),使得(q1->content)小于(p->content)Node*p=h,*p1=NULL;//p指向A部分第一个元素;p1指向p指向的前一个结点,初始化为空while(p!=NULL&&q1->content>p->content){p1=p;p=p->next;} 103if(p1!=NULL){q1->next=p;p1->next=q1;}else{q1->next=h;h=q1;}}}1、下面的求n!的函数有什么问题?intfactorial(int&n){intf=1;while(n>1){f*=n;n--;}returnf;}答:有函数副作用的问题。函数执行结束后,调用该函数的实参值被改变了(通过形参,变为1)。2、写出例5-11名表查找中折半查找的递归函数。解:#includeusingnamespacestd;intb_search(charkey[],TableItemt[],intfirst,intlast){if(first>last)return-1;intindex=(first+last)/2;intr=strcmp(key,t[index]);if(r==0)//key等于t[index]returnindex;elseif(r>0)//key大于t[index]returnb_search(key,t,index+1,last);else//key小于t[index]returnb_search(key,t,first,index-1);}intbinary_search(charkey[],TableItemt[],intnum_of_items){returnb_search(key,t,0,num_of_items-1);}3、编写一个程序解八皇后问题。八皇后问题是:设法在国际象棋的棋盘上放置八个皇后,使得其中任何一个皇后所处的“行”、“列”以及“对角线”上都不能有其它的皇后。解:#include 103boola[8];//a[i]表示第i行是否可以放皇后boolb[15];//b[k]表示“从左下往右上”("/")的第k个对角线是否可以放皇后boolc[15];//c[k]表示“从左上往右下”("")的第k个对角线是否可以放皇后//与棋盘第i行、第j列的格子所对应的行和对角线为:a[i],b[i+j],c[j-i+7]intx[8];//x[j]表示第j列上皇后的位置(所在的行)。booltry_by_col(intj){for(inti=0;i<8;i++)//选择第j列中可放皇后的行,然后递归选择第j+1列可放皇后的行...。{if(a[i]&&b[i+j]&&c[j-i+7])//第j列第i行的位置所在的行以及两个对角线上无皇后。{x[j]=i;//设置第j列皇后的位置。a[i]=b[i+j]=c[j-i+7]=false;//把第j列皇后所在的行以及两个对角线设为已占用。if(j==7||try_by_col(j+1))//是最后一列或第j+1列皇后位置选择成功。returntrue;else//第j+1列皇后位置选择失败。a[i]=b[i+j]=c[j-i+7]=true;//取消第j列皇后位置,准备选择下一个位置。}}returnfalse;}intmain(){inti,j,k;//初始化:所有行以及对角线可放皇后。for(i=0;i<8;i++)a[i]=true;for(k=0;k<15;k++)b[k]=true;for(k=0;k<15;k++)c[k]=true;if(try_by_col(0))//从第0列开始尝试放皇后的位置。{//x[0],x[1],...,x[7]分别为第一列、第二列、...、第七列上皇后的位置(所在的行)for(j=0;j<8;j++)//按列输出皇后{for(i=0;i#includeusingnamespacestd;classPoint{public:Point(){x=y=0;}Point(doublea,doubleb){x=a;y=b;}doubler()//计算极坐标的极半径{returnsqrt(x*x+y*y);}doubletheta()//计算极坐标的极角{returnatan(y/x);}doubledistance(constPoint&p)//计算与点p的距离{returnsqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));}Pointrelative(constPoint&p)//计算相对于p的相对坐标{doublexTemp,yTemp;xTemp=x-p.x;yTemp=y-p.y;returnPoint(xTemp,yTemp);} 103boolis_above_left(constPoint&p)//判断是否在点p的左上方{if((x==p.x)&&(y==p.y))returnfalse;elseif((xp.y))returntrue;elsereturnfalse;}private:doublex;doubley;};1、定义一个时间类Time,它能表示:时、分、秒,并提供以下操作:(1)Time(inth,intm,ints);//构造函数(2)set(inth,intm,ints);//调整时间(3)increment();//时间增加一秒。(4)display();//显示时间值。(5)equal(Time&other_time);//比较是否与某个时间相等。(6)less_than(Time&other_time);//比较是否早于某个时间。答:#includeusingnamespacestd;classTime{public:Time(){hour=minute=second=0;}Time(inth,intm,ints){hour=h;minute=m;second=s;}voidset(inth,intm,ints){hour=h;minute=m;second=s;}voidincrement(){if(second==59){if(minute==59){if(hour==23){hour=0;minute=0;second=0;} 103else{hour++;minute=0;second=0;}}else{minute++;second=0;}}elsesecond++;}voiddisplay()const{cout<usingnamespacestd;classDate{public:Date(inty,intm,intd){year=y;month=m;day=d;}voidincrement();protected: 103intyear,month,day;};voidDate::increment(){intd;switch(month){case1:case3:case5:case7:case8:case10:case12:d=31;break;case4:case6:case9:case11:d=30;break;case2:if(year%400==0||year%4==0&&year%100!=0)//闰年d=29;elsed=28;}if(dayusingnamespacestd;classDate{public:Date(){year=month=day=0;}Date(inta,intb,intc){year=a;month=b;day=c;}voidincrement();protected:intyear,month,day;boolLegal(inty,intm,intd);boolIsLeapYear(inty);};voidDate::increment(){if(Legal(year,month,day+1))day++; 103elseif(Legal(year,month+1,1)){month++,day=1;}elseif(Legal(year+1,1,1)){day=1,month=1,year++;}}boolDate::Legal(inty,intm,intd){if(y>9999||y<1||d<1||m<1||m>12)returnfalse;intdayLimit=31;switch(m){case4:case6:case9:case11:dayLimit--;}if(m==2)dayLimit=IsLeapYear(y)?29:28;return(d>dayLimit)?false:true;}boolDate::IsLeapYear(inty){return!(y%4)&&(y%100)||!(y%400);}1、为例6-3中的字符串类String增加下面的成员函数:(1)boolis_substring(constchar*str);//判断str是否为当前字符串的子串。(2)boolis_substring(constString&str);//判断str是否为当前字符串的子串。(3)Stringsubstring(intstart,intlength);//取从位置start开始、长度为length的子串。(4)intfind_replace_str(constchar*find_str,constchar*replace_str);//查找所有子串find_str并替换成replace_str,返回替换的次数。(5)voidremove_spaces();//删除字符串中的空格。(6)intto_int();//把由数字构成的字符串转成int类型的值。(7)voidto_lower_case();//把字符串中的大写字母转成小写字母。答:boolString::is_substring(constchar*p){intlen_sub=strlen(p);intcount=strlen(str)-len_sub;for(inti=0;i<=count;i++)if(strncmp(p,str+i,len_sub)==0)returntrue;returnfalse;}boolString::is_substring(constString&s) 103{returnis_substring(s.str);}StringString::substring(intstart,intlength){char*temp=newchar[length+1];strncpy(temp,str+start,length);temp[length]="";Stringsstr(temp);delete[]temp;returnsstr;}intString::find_replace_str(constchar*find_str,constchar*replace_str){intcount=0,find_len=strlen(find_str),replace_len=strlen(replace_str);char*p=str;while(*p!=""){if(strncmp(p,find_str,find_len)==0){count++;p+=find_len;}elsep++;}if(count==0)return0;char*str1=newchar[strlen(str)-count*find_len+count*replace_len+1];char*q=str1;p=str;while(*p!=""){if(strncmp(p,find_str,find_len)==0){strcpy(q,replace_str);q+=replace_len;p+=find_len;}else{*q=*p;q++;p++;}}delete[]str;str=str1;returncount;}voidString::remove_spaces(){find_replace_str("","");}intString::to_int(){intstr_int=0;for(inti=0;str[i]!="";i++)str_int=str_int*10+(str[i]-"0"); 103returnstr_int;}voidString::to_lower_case(){for(inti=0;str[i]!="";i++){if(str[i]>="A"&&str[i]<="Z")str[i]=str[i]-"A"+"a";}}1、定义一个元素类型为int、元素个数不受限制的集合类IntSet,该类具有下面的接口:classIntSet{...public:IntSet();IntSet(constIntSet&s);~IntSet();boolis_empty()const;//判断是否为空集。intsize()const;//获取元素个数。boolis_element(inte)const;//判断e是否属于集合。boolis_subset(constIntSet&s)const;//判断s是否包含于集合。boolis_equal(constIntSet&s)const;//判断集合是否相等。voiddisplay()const;//显示集合中的所有元素。IntSet&insert(inte);//将e加入到集合中。IntSet&remove(inte);//把e从集合中删除。IntSetunion2(constIntSet&s)const;//计算集合的并集。IntSetintersection2(constIntSet&s)const;//计算集合的交集。IntSetdifference2(constIntSet&s)const;//计算集合的差。};答:#includeusingnamespacestd;structNode{intvalue;Node*next;};classIntSet{public:IntSet();IntSet(constIntSet&s);~IntSet();boolis_empty()const;//判断是否为空集。intsize()const;//获取元素个数。boolis_element(inte)const;//判断e是否属于集合。boolis_subset(constIntSet&s)const;//判断s是否包含于集合。 103boolis_equal(constIntSet&s)const;//判断集合是否相等。voiddisplay()const;//显示集合中的所有元素。IntSet&insert(inte);//将e加入到集合中。IntSet&remove(inte);//把e从集合中删除。IntSetunion(constIntSet&s)const;//计算集合的并集。IntSetintersection(constIntSet&s)const;//计算集合的交集。IntSetdifference(constIntSet&s)const;//计算集合的差。private:intcount;Node*head;};IntSet::IntSet(){count=0;head=NULL;}IntSet::IntSet(constIntSet&s){head=NULL;count=0;Node*p=s.head;for(inti=0;ivalue);p=p->next;}}IntSet::~IntSet(){Node*p;while(head!=NULL){p=head;head=head->next;deletep;}count=0;}boolIntSet::is_empty()const{returncount==0?true:false;}intIntSet::size()const{returncount;}boolIntSet::is_element(inte)const{for(Node*p=head;p!=NULL;p=p->next)if(p->value==e)returntrue;returnfalse;}boolIntSet::is_subset(constIntSet&s)const 103{for(Node*p=s.head;p!=NULL;p=p->next)if(!is_element(p->value))returnfalse;returntrue;}boolIntSet::is_equal(constIntSet&s)const{if(count!=s.count)returnfalse;elseif(s.is_subset(*this)&&is_subset(s))returntrue;elsereturnfalse;}voidIntSet::display()const{for(Node*p=head;p!=NULL;p=p->next)cout<value<<"t";cout<value=e;p->next=head;head=p;count++;}return*this;}IntSet&IntSet::remove(inte){if(is_element(e)){if(head->value==e){Node*p=head;head=head->next;deletep;}else{for(Node*p=head;p->next!=NULL;p=p->next){if(p->next->value==e){Node*temp=p->next;p->next=temp->next;deletetemp;break;}}}count--;}return*this;} 103IntSetIntSet::union2(constIntSet&s)const{IntSetset(s);Node*p=head;while(p!=NULL){if(!set.is_element(p->value))set.insert(p->value);p=p->next;}returnset;}IntSetIntSet::intersection2(constIntSet&s)const{IntSetset;Node*p=head;while(p!=NULL){if(s.is_element(p->value))set.insert(p->value);p=p->next;}returnset;}IntSetIntSet::difference2(constIntSet&s)const{IntSetset;Node*p=head;while(p!=NULL){if(!s.is_element(p->value))set.insert(p->value);p=p->next;}returnset;}1、定义一个由int型元素所构成的线性表类LinearList,它有下面的成员函数:boolinsert(intx,intpos);//在位置pos之后插入一个元素x。//pos为0时,在第一个元素之前插入。//操作成功时返回true,否则返回false。boolremove(int&x,intpos);//删除位置pos处的元素。//操作成功时返回true,否则返回false。intelement(intpos)const;//返回位置pos处的元素。intsearch(intx)const;//查找值为x的元素,返回元素的位置(第一个元素的位置为1)。未找到时返回0。intlength()const;//返回元素个数。答:#includeusingnamespacestd;classLinearList{public: 103LinearList(){count=0;head=NULL;}~LinearList(){while(head!=NULL){Node*p=head;head=head->next;deletep;}count=0;}boolinsert(intx,intpos);//在位置pos之后插入一个元素x。//pos为0时,在第一个元素之前插入。//操作成功时返回true,否则返回false。boolremove(int&x,intpos);//删除位置pos处的元素。//操作成功时返回true,否则返回false。intelement(intpos)const;//返回位置pos处的元素。intsearch(intx)const;//查找值为x的元素,返回元素的位置(第一个元素的位置为1)。//未找到时返回0。intlength()const;//返回元素个数。private:structNode{intvalue;Node*next;};intcount;Node*head;};boolLinearList::insert(intx,intpos){if(pos>count||pos<0)returnfalse;Node*q=newNode;q->value=x;q->next=NULL;if(pos==0){q->next=head;head=q;}else{Node*p=head;for(inti=1;inext;q->next=p->next;p->next=q;}count++;returntrue;}boolLinearList::remove(int&x,intpos){if(pos>count||pos<=0)returnfalse;Node*p=head; 103if(pos==1){head=head->next;x=p->value;deletep;}else{for(inti=2;inext;Node*temp=p->next;p->next=temp->next;x=temp->value;deletetemp;}count--;returntrue;}intLinearList::element(intpos)const{if(pos>0&&pos<=count){Node*p=head;for(inti=1;inext;returnp->value;}return-1;}intLinearList::search(intx)const{intpos=0;Node*p=head;while(p!=NULL){pos++;if(p->value==x)returnpos;p=p->next;}return0;}intLinearList::length()const{returncount;}1、定义一个类A,使得在程序中只能创建一个该类的对象,当试图创建该类的第二个对象时,返回第一个对象的指针。答://DesignofclassSingleton:classSingleton{public:staticSingleton*Instance();protected:Singleton(); 103private:staticSingleton*_instance;}Singleton*Singleton::_instance=0;Singleton*Singleton::Instance(){if(_instance==0){_instance=newSingleton;}return_instance;};//HowtoUseSingleton:Singleton*singleton=Singleton::Instance();1、对于下面的类A,如何用C++的非面向对象语言成分来实现它?classA{public:A(){x=y=0;}A(inti,intj){x=i;y=j;}voidf(){h();......}voidg(inti){x=i;......}private:intx,y;voidh(){......}};答:(下面的解决方案没考虑inline函数)//A.hstructA{void*p_data;};voidA_A(structA*p_a);voidA_A(structA*p_a,inti,intj);voidA_f(structA*p_a);voidA_g(structA*p_a,inti);//A.cpp#include#include"A.h"structA_Data{intx,y;};voidA_A(structA*p_a){structA_Data*p;p=(structA_Data*)malloc(sizeof(structA_Data));p->x=p->y=0;p_a->p_data=p;} 103voidA_A(structA*p_a,inti,intj){structA_Data*p;p=(structA_Data*)malloc(sizeof(structA_Data));p->x=i;p->y=j;p_a->p_data=p;}externvoidA_h(structA*p_a);voidA_f(A*p_a){A_h(p_a);......}voidA_g(structA*p_a,inti){structA_Data*p=(structA_Data*)p_a->p_data;p->x=i;......}staticvoidA_h(structA*p_a){......}第7章操作符重载1、为什么要对操作符进行重载?是否所有的操作符都可以重载?答:通过对C++操作符进行重载,我们可以实现用C++的操作符按照通常的习惯来对某些类(特别是一些数学类)的对象进行操作,从而使得程序更容易理解。除此之外,操作符重载机制也提高了C++语言的灵活性和可扩充性,它使得C++操作符除了能对基本数据类型和构造数据类型进行操作外,也能用它们来对类的对象进行操作。不是所有的操作符都可以重载,因为“.”,“.*”,“::”,“?:”,sizeof这五个操作符不能重载。2、操作符重载的形式有哪两种形式?这两种形式有什么区别?答:一种就是作为成员函数重载操作符;另一种就是作为全局(友元)函数重载操作符。当操作符作为类的非静态成员函数来重载时,由于成员函数已经有一个隐藏的参数this,因此对于双目操作符重载函数只需要提供一个参数,对于单目操作符重载函数则不需提供参数。当操作符作为全局函数来重载时,操作符重载函数的参数类型至少有一个为类、结构、枚举或它们的引用类型。而且如果要访问参数类的私有成员,还需要把该函数说明成相应类的友元。对于双目操作符重载函数需要两个参数,对于单目操作符重载函数则需要给出一个参数。操作符=、()、[]以及->不能作为全局函数来重载。另外,作为类成员函数来重载时,操作符的第一个操作数必须是类的对象,全局函数重载则否。3、 103定义一个时间类Time,通过操作符重载实现:时间的比较(==、!=、>、>=、<、<=)、时间增加/减少若干秒(+=、-=)、时间增加/减少一秒(++、--)以及两个时间相差的秒数(-)。解:classTime{private:inthour,minute,second;public:Time(){hour=minute=second=0;}Time(inth){hour=h;minute=second=0;}Time(inth,intm){hour=h;minute=m;second=0;}Time(inth,intm,ints){hour=h;minute=m;second=s;}Time(constTime&t){hour=t.hour;minute=t.minute;second=t.second;}booloperator==(Time&t){if(hour==t.hour&&minute==t.minute&&second==t.second)returntrue;returnfalse;}booloperator!=(Time&t){return!(*this==t);}booloperator>(Time&t){if(hour>t.hour)returntrue;elseif(hour==t.hour&&minute>t.minute)returntrue;elseif(hour==t.hour&&minute==t.minute&&second>t.second) 103returntrue;elsereturnfalse;}booloperator>=(Time&t){return*this>t||*this==t;}booloperator<(Time&t){return!(*this>=t);}booloperator<=(Time&t){return!(*this>t);}Time&operator+=(ints){second+=s;while(second>=60){second-=60;minute++;}while(minute>=60){minute-=60;hour++;}while(hour>=24)hour-=24;return*this;}Time&operator-=(ints){second-=s;while(second<0){second+=60;minute--;}while(minute<0){minute+=60;hour--;}while(hour<0)hour+=24;return*this;}Time&operator++()//对Timet,操作为:++t{*this+=1;return*this;} 103Timeoperator++(int)//对Timet,操作为:t++{Timet=*this;*this+=1;returnt;}Time&operator--(){*this-=1;return*this;}Timeoperator--(int){Timet=*this;*this-=1;returnt;}intoperator-(Time&t){//把时间直接换算成秒数计算intsec1=hour*3600+minute*60+second;intsec2=t.hour*3600+t.minute*60+t.second;returnsec2-sec1;}};1、利用操作符重载给出一个完整的复数类的定义。解:classComplex{private:doublereal,imag;public:Complex(){real=imag=0;}Complex(doubler){real=r;imag=0;}Complex(doubler,doublei){real=r;imag=i;}Complex(constComplex&c){real=c.real;imag=c.imag;}doublemodulus()const{returnreal*real+imag*imag;}Complexoperator-()const{Complextemp; 103temp.real=-real;temp.imag=-imag;returntemp;}friendbooloperator==(constComplex&c1,constComplex&c2);friendbooloperator!=(constComplex&c1,constComplex&c2);friendbooloperator>(constComplex&c1,constComplex&c2);friendbooloperator>=(constComplex&c1,constComplex&c2);friendbooloperator<(constComplex&c1,constComplex&c2);friendbooloperator<=(constComplex&c1,constComplex&c2);friendComplexoperator+(constComplex&c1,constComplex&c2);friendComplexoperator-(constComplex&c1,constComplex&c2);friendComplexoperator*(constComplex&c1,constComplex&c2);friendComplexoperator/(constComplex&c1,constComplex&c2);};booloperator==(constComplex&c1,constComplex&c2){return(c1.real==c2.real)&&(c1.imag==c2.imag);}booloperator!=(constComplex&c1,constComplex&c2){return!(c1==c2);}booloperator>(constComplex&c1,constComplex&c2){returnc1.modulus()>c2.modulus();}booloperator>=(constComplex&c1,constComplex&c2){returnc1.modulus()>=c2.modulus();}booloperator<(constComplex&c1,constComplex&c2){returnc1.modulus()1;i--){boolexchange=false;for(intj=1;jusingnamespacestd;structNode{intvalue;Node*next;};classIntSet{public:IntSet();IntSet(constIntSet&s);~IntSet();boolis_empty()const;//判断是否为空集。intsize()const;//获取元素个数。boolis_element(inte)const;//判断e是否属于集合。voiddisplay()const;//显示集合中的所有元素。booloperator<=(constIntSet&s)const;//判断s是否包含于集合。booloperator==(constIntSet&s)const;//判断集合是否相等。booloperator!=(constIntSet&s)const;//判断集合是否不相等。IntSet&operator+=(inte);//将e加入到集合中。IntSet&operator-=(inte);//把e从集合中删除。IntSetoperator|(constIntSet&s)const;//计算集合的并集。IntSetoperator&(constIntSet&s)const;//计算集合的交集。IntSetoperator-(constIntSet&s)const;//计算集合的差。IntSet&operator=(constIntSet&s);//集合赋值private:intcount;Node*head;};IntSet::IntSet(){count=0;head=NULL;}IntSet::IntSet(constIntSet&s){head=NULL;count=0;Node*p=s.head; 103for(inti=0;ivalue);p=p->next;}}IntSet::~IntSet(){Node*p;while(head!=NULL){p=head;head=head->next;deletep;}count=0;}boolIntSet::is_empty()const{returncount==0?true:false;}intIntSet::size()const{returncount;}boolIntSet::is_element(inte)const{for(Node*p=head;p!=NULL;p=p->next)if(p->value==e)returntrue;returnfalse;}boolIntSet::operator<=(constIntSet&s)const{for(Node*p=s.head;p!=NULL;p=p->next)if(!is_element(p->value))returnfalse;returntrue;}boolIntSet::operator==(constIntSet&s)const{if(count!=s.count)returnfalse;elseif(*this<=s&&s<=*this)returntrue;elsereturnfalse;}boolIntSet::operator!=(constIntSet&s)const{return!(*this==s);}voidIntSet::display()const{for(Node*p=head;p!=NULL;p=p->next)cout<value<<"t";cout<value=e;p->next=head;head=p;count++;}return*this;}IntSet&IntSet::operator-=(inte){if(is_element(e)){if(head->value==e){Node*p=head;head=head->next;deletep;}else{for(Node*p=head;p->next!=NULL;p=p->next){if(p->next->value==e){Node*temp=p->next;p->next=temp->next;deletetemp;break;}}}count--;}return*this;}IntSetIntSet::operator|(constIntSet&s)const{IntSetset(s);Node*p=head;while(p!=NULL){if(!set.is_element(p->value))set+=p->value;p=p->next;}returnset;}IntSetIntSet::operator&(constIntSet&s)const{IntSetset;Node*p=head;while(p!=NULL){if(s.is_element(p->value))set+=p->value;p=p->next; 103}returnset;}IntSetIntSet::operator-(constIntSet&s)const{IntSetset;Node*p=head;while(p!=NULL){if(!s.is_element(p->value))set+=p->value;p=p->next;}returnset;}IntSet&IntSet::operator=(constIntSet&s){Node*p;while(head!=NULL){p=head;head=head->next;deletep;}count=0;p=s.head;for(inti=0;ivalue);p=p->next;}return*this;}1、定义一个带下标范围检查、数组整体赋值和比较功能的一维int型数组类:IntArray。解:#includeusingnamespacestd;classIntArray{int*p_buf;intsize;public:IntArray(intn){size=n;p_buf=newint[size];for(inti=0;i=size){cerr<<"超出数组范围!n";exit(-1);}returnp_buf[i];}intoperator[](inti)const//取某位置上的字符,用于常量对象{if(i<0||i>=size){cerr<<"超出数组范围!n";exit(-1);}returnp_buf[i];}IntArray&operator=(IntArray&x){if(&x==this)return*this;if(size!=x.size){cerr<<"两个数组尺寸不同!n";exit(-1);}for(inti=0;i#includeusingnamespacestd;classINT{char*p_buf;//从低位到高位存储整型数,intbuf_len,//p_buf所占空间大小(为10的倍数)sign;//整型数的符号(1为正,-1为负)voidAdd(constINT&i);//把i加到*this中 103voidMinus(constINT&i);//从*this中减去iINT(char*p,intlen,ints=1);//新对象的p_buf在已有的空间p上(不再另外分配空间)。public:INT();INT(inti);INT(char*num);INT(constINT&i);~INT();INT&operator=(constINT&i);INT&INT::operator+=(constINT&i);INT&INT::operator-=(constINT&i);friendINToperator+(constINT&i1,constINT&i2);friendINToperator-(constINT&i1,constINT&i2);friendINToperator*(constINT&i1,constINT&i2);friendINToperator/(constINT&i1,constINT&i2);friendostream&operator<<(ostream&out,constINT&i);};INT::INT(){sign=1;buf_len=10;p_buf=newchar[buf_len+1];p_buf[0]="0";p_buf[1]="";}INT::INT(inti){if(i>=0)sign=1;else{sign=-1;i=-i;}intj=i,k=0;do{k++;j/=10;}while(j!=0);buf_len=(k/10+1)*10;p_buf=newchar[buf_len+1];j=0;do{k=i%10;p_buf[j++]=k+"0";i/=10;}while(i!=0);p_buf[j]="";}INT::INT(char*num){if(*num=="-") 103{sign=-1;num++;}elseif(*num=="+"){sign=1;num++;}elsesign=1;buf_len=(strlen(num)/10+1)*10;p_buf=newchar[buf_len+1];for(inti=0,j=strlen(num)-1;j>=0;i++,j--)p_buf[i]=num[j];p_buf[i]="";}INT::INT(constINT&i){sign=i.sign;buf_len=i.buf_len;p_buf=newchar[buf_len+1];strcpy(p_buf,i.p_buf);}INT::INT(char*p,intlen,ints){p_buf=p;buf_len=len;sign=s;}INT::~INT(){delete[]p_buf;p_buf=NULL;buf_len=0;}INT&INT::operator=(constINT&i){sign=i.sign;if(buf_lenlen2?len1:len2)+1)/10+1)*10;if(buf_len1>buf_len){char*p_buf1=newchar[buf_len1+1];strcpy(p_buf1,p_buf); 103delete[]p_buf;p_buf=p_buf1;buf_len=buf_len1;}char*p1,*p2;//p1指向长的数,p2指向短的数if(len1>=len2){p1=p_buf;p2=i.p_buf;}else{p1=i.p_buf;p2=p_buf;}intcarry=0,sum;char*p=p_buf;//处理公共长度部分while(*p2!=""){sum=(*p1-"0")+(*p2-"0")+carry;if(sum>=10){carry=1;*p=(sum-10)+"0";}else{carry=0;*p=sum+"0";}p1++;p2++;p++;}//处理较大整数的剩余部分while(*p1!=""){if(carry==0)*p=*p1;else{sum=(*p1-"0")+carry;if(sum>=10){carry=1;*p=(sum-10)+"0";}else{carry=0;*p=sum+"0";}}p1++;p++;}if(carry!=0)//最后检查是否还有进位,若有就放入和的最高位{*p="1";p++;}*p=""; 103}voidINT::Minus(constINT&i)//绝对值减,*this-i{intlen1=strlen(p_buf);intlen2=strlen(i.p_buf);intbuf_len1=((len1>len2?len1:len2)/10+1)*10;if(buf_len1>buf_len){char*p_buf1=newchar[buf_len1+1];strcpy(p_buf1,p_buf);delete[]p_buf;p_buf=p_buf1;buf_len=buf_len1;}char*p1,*p2;if(len1>len2)p1=p_buf;elseif(len1=0;j--){if(p_buf[j]>i.p_buf[j]){p1=p_buf;break;}elseif(p_buf[j]sign=-p->sign;//把i变成-i*this+=*p;//*this+=-ip->sign=-p->sign;//把i还原return*this; 103}INToperator-(constINT&i1,constINT&i2){INTtemp(i1);temp-=i2;returntemp;}INToperator*(constINT&i1,constINT&i2){intlen1=strlen(i1.p_buf);intlen2=strlen(i2.p_buf);intbuf_len=((len1+len2)/10+1)*10;char*p_buf=newchar[buf_len+1];INTproduct,temp(p_buf,buf_len,1);//用一个乘数(i1)的每一位与另一个乘数(i2)相乘,结果(temp)向左移相应的位数后加到乘积(product)中去for(intj=0;j0)//直到被除数小于零{quotient+=1;//每减一次除数,计数器加1div1-=div2;//用被除数减去除数}if(i1.sign==i2.sign)//最后统一处理商的符号quotient.sign=1;elsequotient.sign=-1; 103returnquotient;}ostream&operator<<(ostream&out,constINT&i){if(i.sign<0)out<<"-";for(intj=strlen(i.p_buf)-1;j>=0;j--)out<//usingnamespacestd;//在visualc++6.0中不要这一行!constintNUM=2;classA{//......//类A的已有成员说明。public: 103staticvoid*operatornew(size_tsize);staticvoidoperatordelete(void*p);staticvoidfree_blocks();//归还申请的所有存储块。private:staticA*p_free;//用于指向A类对象的自由空间链表。A*next;//用于实现自由空间结点的链接。staticchar*p_block;//用于指向由NUM个A类对象所组成的存储块所构成的链表。};A*A::p_free=NULL;char*A::p_block=NULL;void*A::operatornew(size_tsize){A*p;if(p_free==NULL){char*q=newchar[sizeof(char*)+size*NUM];//申请一个块指针和NUM个A类对象所构成的堆空间。*(char**)q=p_block;//建立存储块链表。p_block=q;p_free=(A*)(q+sizeof(char*));//跳过块指针。for(p=p_free;p!=p_free+NUM-1;p++)//建立自由结点链表。p->next=p+1;p->next=NULL;}p=p_free;//为当前创建的对象分配空间。p_free=p_free->next;memset(p,0,size);returnp;}voidA::operatordelete(void*p){((A*)p)->next=p_free;p_free=(A*)p;}voidA::free_blocks()//归还申请的所有存储块。{while(p_block!=NULL){char*p=p_block;p_block=*(char**)p_block;delete[]p;}} 103第8章继承――派生类1、在C++中,protected类成员访问控制有什么作用?答:C++中引进protected成员保护控制,缓解了数据封装与继承的矛盾。在基类中声明为protected的成员可以被派生类使用,但不能被基类的实例用户使用,这样能够对修改基类的内部实现所造成的影响范围(只影响子类)进行控制。protected成员保护控制的引进使得类有两种接口:与实例用户的接口和与派生类用户的接口。2、在C++中,三种继承方式各有什么作用?答:类的继承方式决定了派生类的对象和派生类的派生类对基类成员的访问限制。public继承方式使得基类的public成员可以被派生类的对象访问,它可以实现类之间的子类型关系;protected继承使得基类的public成员不能被派生类的对象访问,但可以被派生类的派生类访问;private继承使得基类的public成员既不能被派生类的对象访问,也不能被派生类的派生类访问。protected和private继承主要用于实现上的继承,即纯粹为了代码复用。3、在多继承中,什么情况下会出现二义性?怎样消除二义性?答:在多继承中会出现两个问题:名冲突和重复继承。在多继承中,当多个基类中包含同名的成员时,它们在派生类中就会出现名冲突问题;在多继承中,如果直接基类有公共的基类,就会出现重复继承,这样,公共基类中的数据成员在多继承的派生类中就有多个拷贝。在C++中,解决名冲突的方法是用基类名受限;解决重复继承问题的手段是采用虚基类。4、写出下面程序的运行结果:#includeusingnamespacestd;classA{intm;public:A(){cout<<"inA"sdefaultconstructorn";}A(constA&){cout<<"inA"scopyconstructorn";}~A(){cout<<"inA"sdestructorn";}};classB{intx,y;public:B(){cout<<"inB"sdefaultconstructorn";}B(constB&){cout<<"inB"scopyconstructorn";}~B(){cout<<"inB"sdestructorn";}};classC:publicB{intz;Aa; 103public:C(){cout<<"inC"sdefaultconstructorn";}C(constC&){cout<<"inC"scopyconstructorn";}~C(){cout<<"inC"sdestructorn";}};voidfunc1(Cx){cout<<"Infunc1n";}voidfunc2(C&x){cout<<"Infunc2n";}intmain(){cout<<"------Section1------n";Cc;cout<<"------Section2------n";func1(c);cout<<"------Section3------n";func2(c);cout<<"------Section4------n";return0;}答:------Section1------inB"sdefaultconstructorinA"sdefaultconstructorinC"sdefaultconstructor------Section2------inB"sdefaultconstructorinA"sdefaultconstructorinC"scopyconstructorInfunc1inC"sdestructorinA"sdestructorinB"sdestructor------Section3------Infunc2------Section4------inC"sdestructorinA"sdestructorinB"sdestructor1、写出下面程序的运行结果:#includeusingnamespacestd;classA 103{intx,y;public:A(){cout<<"inA"sdefaultconstructorn";f();}A(constA&){cout<<"inA"scopyconstructorn";f();}~A(){cout<<"inA"sdestructorn";}virtualvoidf(){cout<<"inA"sfn";}voidg(){cout<<"inA"sgn";}voidh(){f();g();}};classB:publicA{intz;public:B(){cout<<"inB"sdefaultconstructorn";}B(constB&){cout<<"inB"scopyconstructorn";}~B(){cout<<"inB"sdestructorn";}voidf(){cout<<"inB"sfn";}voidg(){cout<<"inB"sgn";}};voidfunc1(Ax){x.f();x.g();x.h();}voidfunc2(A&x){x.f();x.g();x.h();}intmain(){cout<<"------Section1------n";Aa;A*p=newB;cout<<"------Section2------n";func1(a);cout<<"------Section3------n";func1(*p);cout<<"------Section4------n";func2(a);cout<<"------Section5------n";func2(*p);cout<<"------Section6------n";deletep;cout<<"------Section7------n";return0;}答:------Section1------inA"sdefaultconstructorinA"sfinA"sdefaultconstructorinA"sf 103inB"sdefaultconstructor------Section2------inA"scopyconstructorinA"sfinA"sfinA"sginA"sfinA"sginA"sdestructor------Section3------inA"scopyconstructorinA"sfinA"sfinA"sginA"sfinA"sginA"sdestructor------Section4------inA"sfinA"sginA"sfinA"sg------Section5------inB"sfinA"sginB"sfinA"sg------Section6------inA"sdestructor------Section7------inA"sdestructor1、利用习题6.8的第14题中的时间类Time,定义一个带时区的时间类ExtTime。除了构造函数和时间调整函数外,ExtTime的其它功能与Time类似。答:#includeusingnamespacestd; 103classTime{public:Time();Time(inth,intm,ints);voidset(inth,intm,ints);voidincrement();voiddisplay()const;boolequal(Time&other_time)const;boolless_than(Time&other_time)const;protected:inthour;intminute;intsecond;};enumTimeZone{W12=-12,W11,W10,W9,W8,W7,W6,W5,W4,W3,W2,W1,GMT,E1,E2,E3,E4,E5,E6,E7,E8,E9,E10,E11,E12};classExtTime:publicTime{public:ExtTime(){tz=GMT;}ExtTime(inth,intm,ints,TimeZonet):Time(h,m,s){tz=t;}voidset(inth,intm,ints,TimeZonet){Time::set(h,m,s);tz=t;}voiddisplay()const{if(tz<0)cout<<"西"<<-int(tz)<<"区t";elseif(tz==0)cout<<"格林威治(子午线)标准时间(GMT)t";elsecout<<"东"<usingnamespacestd;classLinearList{public:LinearList();~LinearList();boolinsert(intx,intpos);boolremove(int&x,intpos);intelement(intpos)const;intsearch(intx)const;intlength()const;private:structNode{intvalue;Node*next;};intcount;Node*head;};//////////////////////////////////////////////////////////////////////classStack:LinearList{public:boolpush(intx);boolpop(int&x);LinearList::length;};boolStack::push(intx){returninsert(x,0);}boolStack::pop(int&x){returnremove(x,1);}1、利用习题6.8的第14、15题中的时间类Time和日期类Date,定义一个带日期的时间类TimeWithDate。对该类对象能进行比较、增加(增加值为秒数)、相减(结果为秒数)等操作。答:#includeusingnamespacestd;classTime{public:Time(){hour=minute=second=0; 103}Time(inth,intm,ints){hour=h;minute=m;second=s;}voidset(inth,intm,ints){hour=h;minute=m;second=s;}voidincrement(){if(second==59){if(minute==59){if(hour==23){hour=0;minute=0;second=0;}else{hour++;minute=0;second=0;}}else{minute++;second=0;}}elsesecond++;}voiddisplay()const{cout<equal(Time(0,0,0)))//或if(hour==0&&minute==0&&second==0)Date::increment();}intTimeWithDate::difference(constTimeWithDate&td2)const{intdays=0;if(less_than(td2))for(TimeWithDatetd=*this;td.less_than(td2);td.increment())days--;elsefor(TimeWithDatetd=td2;td.less_than(*this);td.increment())days++;returndays;}voidTimeWithDate::display()const{Date::display();cout<<"";Time::display();}1、如何定义两个类A和B(B是A的派生类),使得在程序中能够创建一个与指针变量p(类型为A*)所指向的对象是同类的对象?答:classA{...public:virtualA*create(){returnnewA;} 103};classB:publicA{...public:A*create(){returnnewB;}};intmain(){A*p;if(...)p=newA;elsep=newB;...A*q;q=p->create();//创建一个与p所指向的对象同类的对象。...}1、下面的设计有什么问题?如何解决?classRectangle//矩形类{public:Rectangle(doublew,doubleh):width(w),height(h){}voidset_width(doublew){width=w;}voidset_height(doubleh){height=h;}doubleget_width()const{returnwidth;}doubleget_height()const{returnheight;}doublearea()const{returnwidth*height;}voidprint()const{cout<1;n--)//基于数的个数n进行循环,每次减少一个数{inti_max=0;//i_max用于保存最大元素的下标,首先假设第0个元素最大for(inti=1;i0)i_max=i;//修改i_max的值,使其一直为最大元素的下标//交换第i_max个和第n-1个元素char*p1=(char*)base+i_max*element_size,*p2=(char*)base+(n-1)*element_size;for(intk=0;k//T为元素类型voidsel_sort(Tx[],intn){for(;n>1;n--)//基于数的个数进行循环,每次减少一个数{inti_max=0;//i_max用于保存最大元素的下标,首先假设第0个元素最大for(inti=1;ix[i_max])i_max=i;//修改i_max的值,使其一直为最大元素的下标 103//交换x[i_max]和x[n-1]的值Ttemp=x[i_max];x[i_max]=x[n-1];x[n-1]=temp;}}1、用类模板定义一个类属的队列类。解:templateclassQueue{Tbuffer[size+1];//size个位置用于存放元素,剩下的一个用于队列管理(空/满)intfront,rear;public:Queue(){front=rear=0;}boolenque(constT&x){if((rear+1)%(size+1)==front)//队列满returnfalse;buffer[rear]=x;rear=(rear+1)%(size+1);returntrue;}booldeque(T&x){if(front==rear)//队列空returnfalse;x=buffer[front];front=(front+1)%(size+1);returntrue;}};2、用STL的容器vector和算法sort实现习题Error!Referencesourcenotfound.中第16题的功能。解:#include#include#include#includeusingnamespacestd;classStudent{stringid;stringname;intscores[8];//这里也可以用一个vector来实现public:voidinput_data(){cin>>id>>name;for(inti=0;i<8;i++)cin>>scores[i]; 103}voiddisplay()const{cout<st2.average();}voiddisplay_student_info(Student&st)//显示st的信息{st.display();cout<students;Studentst;intt;for(cin>>t;t!=-1;cin>>t)//循环输入每个学生的信息,输入每个学生信息前先输入一个是否结束的标记(-1表示结束){st.input_data();students.push_back(st);}sort(students.begin(),students.end(),compare_average);for_each(students.begin(),students.end(),display_student_info);return0;}1、用STL的容器map和算法find_if实现Error!Referencesourcenotfound.的名表表示和查找功能。//顺序查找#include#include#include#includeusingnamespacestd;mapname_table;classMatchName{stringname;public:MatchName(strings) 103{name=s;}booloperator()(pairv){returnv.first==name;}};intmain(){name_table["北京"]=10;name_table["上海"]=21;name_table["南京"]=25;name_table["广州"]=20;name_table["武汉"]=27;name_table["哈尔滨"]=451;name_table["西藏"]=891;map::const_iteratorit;//创建一个不能修改所指向的元素的迭代器for(it=name_table.begin();it!=name_table.end();it++)//遍历容器cout<first<<":"<second<first<<":"<second<#include#includeusingnamespacestd;classCompare{intvalue;public:Compare(inti){value=i;}booloperator()(inti){returni<=value;}};voidqsort(vector::iteratorit1,vector::iteratorit2){if(it2-it1<2)return;//元素个数小于2,返回vector::iteratorit=partition(it1,it2,Compare(*it1));//取第一个元素作为分隔元素,it-1为分隔位置//交换分隔元素与分隔位置上元素的位置inttemp=*(it-1); 103*(it-1)=*it1;*it1=temp;qsort(it1,it-1);//对分隔位置之前的元素排序qsort(it,it2);//对分隔位置之后的元素排序}intmain(){vectorv;v.push_back(5);v.push_back(10);v.push_back(8);v.push_back(3);v.push_back(6);v.push_back(7);v.push_back(4);v.push_back(1);v.push_back(2);v.push_back(9);qsort(v.begin(),v.end());//输出排序后容器v的元素vector::iteratorit1=v.begin();vector::iteratorit2=v.end();while(it1!=it2){cout<<*it1<<"";++it1;}cout<#include#include#includeusingnamespacestd;classIntSet{setiset;public:IntSet(){};IntSet(constIntSet&s){for(set::const_iteratorit1=s.iset.begin(),it2=s.iset.end();it1!=it2;it1++)iset.insert(*it1);};~IntSet(){};boolis_empty()const//判断是否为空集 103{returniset.empty();}intsize()const//获取元素个数{returniset.size();}boolis_element(inte)const//判断e是否属于集合{returniset.find(e)!=iset.end();}boolis_subset(constIntSet&s)const//判断s是否包含于集合{returnincludes(iset.begin(),iset.end(),s.iset.begin(),s.iset.end());}boolis_equal(constIntSet&s)const//判断集合是否相等{returnincludes(iset.begin(),iset.end(),s.iset.begin(),s.iset.end())&&includes(s.iset.begin(),s.iset.end(),iset.begin(),iset.end());}voiddisplay()const//显示集合中的所有元素{for(set::const_iteratorit1=iset.begin(),it2=iset.end();it1!=it2;it1++)cout<<*it1<<"";cout<v(iset.size()+s.iset.size());vector::iteratorit=set_union(iset.begin(),iset.end(),s.iset.begin(),s.iset.end(),v.begin());IntSettmp;tmp.iset.insert(v.begin(),it);returntmp;}IntSetintersection2(constIntSet&s)const//计算集合的交集{vectorv(iset.size());vector::iteratorit=set_intersection(iset.begin(),iset.end(),s.iset.begin(),s.iset.end(),v.begin());IntSettmp;tmp.iset.insert(v.begin(),it);returntmp;}IntSetdifference2(constIntSet&s)const//计算集合的差{vectorv(iset.size());vector::iteratorit=set_difference(iset.begin(),iset.end(),s.iset.begin(),s.iset.end(),v.begin());IntSettmp;tmp.iset.insert(v.begin(),it); 103returntmp;}};1、对一个元素为int型的容器,用STL的算法for_each计算该容器中所有大于某个值的元素的和。#include#include#includeusingnamespacestd;classMatchSum{intsum;intvalue;public:MatchSum(intv){sum=0;value=v;}voidoperator()(inti){if(i>value)sum+=i;}intget_sum(){returnsum;}};intmain(){vectorvec;vec.push_back(1);vec.push_back(2);vec.push_back(3);vec.push_back(4);vec.push_back(5);vec.push_back(6);vec.push_back(7);vec.push_back(8);vec.push_back(9);cout<#includeusingnamespacestd;intmain(intargc,char*argv[]){if(argc!=3){cout<<"copyn"; 103return-1;}ifstreamin_file(argv[1],ios::in|ios::binary);if(!in_file){cout<<"sourcefileopenfailure!n";exit(-1);}ofstreamout_file(argv[2],ios::out|ios::binary);if(!out_file){cout<<"destinationfileopenfailure!n";exit(-1);}charch;in_file.get(ch);while(!in_file.eof()){out_file.put(ch);in_file.get(ch);}in_file.close();out_file.close();return0;}1、编写一个程序,统计一个文本文件的行数。//lines.cpp#include#includeusingnamespacestd;intmain(intargc,char*argv[]){if(argc!=2){cout<<"linesn";return-1;}ifstreamin_file(argv[1],ios::in);if(!in_file){cout<<"sourcefileopenfailure!n";exit(-1);}charstr[1024];//文件的每一行最大字符数不能超过1024intcount=0;//用于行数统计while(!in_file.eof()){count++;in_file.getline(str,1024);}in_file.close();cout<>”来实现通讯录的输入/输出。#include#include#includeusingnamespacestd;classAddressBook{unsignedintno;charname[20];charaffiliation[40];charphone_no[20];public:AddressBook(){no=0;}friendistream&operator>>(istream&in,AddressBook&item);friendostream&operator<<(ostream&out,AddressBook&item);};istream&operator>>(istream&in,AddressBook&item){item.no++;cout<<"序号:"<>setw(20)>>item.name;cout<<"工作单位:";in>>setw(40)>>item.affiliation;cout<<"电话号码:";in>>setw(20)>>item.phone_no;returnin;}ostream&operator<<(ostream&out,AddressBook&item){out<>ab;out_file<>ch;}out_file.close();return0;}1、用文本文件保存Error!Referencesourcenotfound.中的学生信息。#includeusingnamespacestd;enumSex{MALE,FEMALE};structDate{intyear;intmonth;intday;};enumMajor{MATHEMATICS,PHYSICS,CHEMISTRY,COMPUTER,GEOGRAPHY,ASTRONOMY,ENGLISH,CHINESE,PHILOSOPHY};intmain(){FILE*fp=fopen("d:\students.txt","w");//以二进制方式打开文件用于输出if(fp==NULL)//判文件打开是否成功{printf("打开文件失败!n");return-1;}charid[11];charname[9];Sexsex;Datebirth_date;charbirth_place[40];Majormajor;printf("学号(以"E"结束):");scanf("%10s",id);//读入第一个学生的学号while(id[0]!="E"){printf("姓名:");scanf("%8s",name);//读入姓名printf("性别(0:male,1:female):");inttemp;scanf("%d",&temp);//读入性别sex=(Sex)temp;printf("出生日期(YYYY/MM/DD):");scanf("%d/%d/%d",&birth_date.year,&birth_date.month,&birth_date.day);//读入出生日期printf("出生地:");scanf("%39s",birth_place);//读入出生地 103printf("专业(0:MATHEMATICS,1:PHYSICS,2:CHEMISTRY,3:COMPUTER,4:GEOGRAPHY,5:ASTRONOMY,6:ENGLISH,7:CHINESE,8:PHILOSOPHY):");scanf("%d",&temp);//读入专业major=(Major)temp;//输出学生信息fprintf(fp,"%s,%s,",id,name);if(sex==MALE)fprintf(fp,"MALE,");elsefprintf(fp,"FEMALE,");fprintf(fp,"%d/%d/%d,",birth_date.year,birth_date.month,birth_date.day);fprintf(fp,"%s,",birth_place);switch(major){caseMATHEMATICS:fprintf(fp,"MATHEMATICSn");break;casePHYSICS:fprintf(fp,"PHYSICSn");break;caseCHEMISTRY:fprintf(fp,"CHEMISTRYn");break;caseCOMPUTER:fprintf(fp,"COMPUTERn");break;caseGEOGRAPHY:fprintf(fp,"GEOGRAPHYn");break;caseASTRONOMY:fprintf(fp,"ASTRONOMYn");break;caseENGLISH:fprintf(fp,"ENGLISHn");break;caseCHINESE:fprintf(fp,"CHINESEn");break;casePHILOSOPHY:fprintf(fp,"PHILOSOPHYn");break;}printf("学号(以"E"结束):");scanf("%10s",id);//读入下一个学生的学号}fclose(fp);//关闭文件return0;}1、从键盘读入一批图形信息,然后把它们保存到文件中。#include#includeusingnamespacestd;intmain(){ofstreamout_file("d:\myfile.txt",ios::out);if(!out_file)return-1;while(1){intshape;do{cout<<"请输入图形的种类(0:线段,1:矩形,2:圆,-1:结束):";cin>>shape;}while(shape<-1||shape>2);if(shape==-1)break;intx1,y1,x2,y2,r;switch(shape){case0://线cout<<"请输入线段的起点和终点坐标(x1y1x2y2):";cin>>x1>>y1>>x2>>y2; 103out_file<<"line:"<>x1>>y1>>x2>>y2;out_file<<"rectangle:"<>x1>>y1>>r;out_file<<"circle:"<#includeusingnamespacestd;intmain(){ifstreamin_file("d:\myfile.txt",ios::in);if(!in_file)return-1;charshape[20];in_file.getline(shape,20,":");while(!in_file.eof()){intx1,y1,x2,y2,r;charch;if(strcmp(shape,"line")==0){in_file>>x1>>ch>>y1>>ch>>x2>>ch>>y2;cout<<"线(x1,y1,x2,y2):"<>x1>>ch>>y1>>ch>>x2>>ch>>y2;cout<<"矩形(x1,y1,x2,y2):"<>x1>>ch>>y1>>ch>>r;cout<<"圆(x,y,r):"<#include#includeusingnamespacestd;intfind_substr(charstr[],charsub_str[]){intlen=strlen(str),//主串长度sub_len=strlen(sub_str);//子串的长度for(inti=0;i<=len-sub_len;i++)//从主串的头开始循环查找子串{//下面的循环在主串中从位置i开始逐个字符与子串中的字符进行比较intj=0;while(j>find_str;intline_count=1;//记住行数,初始化为1charbuffer[1024];//用于存放文本中的行,每行最长1023个字符in_file.getline(buffer,1024);while(!in_file.eof()){cout<line:"<#includeusingnamespacestd;structStudent 103{charid[20];charname[20];intaverage_score;}students[300];//假设最多300个学生voidsort_by_average(Studentsts[],intnum){for(inti=0;ists[k].average_score)k=j;if(k!=i){Studenttemp=sts[i];sts[i]=sts[k];sts[k]=temp;}}}intmain(){ifstreamin_file("d:\myfile.txt",ios::in);//输入文件每一行按下面格式:学号,姓名,成绩1,成绩2,...,成绩8if(!in_file)return-1;intindex=0;//学生数组下标in_file.getline(students[index].id,20,",");while(!in_file.eof()){in_file.getline(students[index].name,20,",");students[index].average_score=0;intscores[8];for(inti=0;i<8;i++){in_file>>scores[i];charch;in_file.get(ch);//读入逗号和回车符students[index].average_score+=scores[i];}students[index].average_score/=8;index++;in_file.getline(students[index].id,20,",");}in_file.close();sort_by_average(students,index);//排序ofstreamout_file("d:\myfile_sort.txt",ios::out);//输出文件每一行按下面格式:学号,姓名,平均成绩if(!out_file)return-1;for(inti=0;iusingnamespacestd;classIntArray{int*p;unsignedintlen;public:IntArray(intn){p=newint[n];len=n;}~IntArray(){delete[]p;p=0;len=0;}int&operator[](inti){if(i<0||i>=len)throw-1;returnp[i];}};intmain(){IntArraya(10);inti;loop:cin>>i; 103try{a[i]=i;}catch(int){cout<<"Errorn";gotoloop;}cout<usingnamespacestd;intdivide(intx,inty){if(y==0)throw0;returnx/y;}voidf(){inta,b;cout<<"请输入两个数:";loop:try{cin>>a>>b;intr=divide(a,b);cout<