C++第5章习题解答.doc 20页

  • 207.00 KB
  • 2022-04-22 11:19:45 发布

C++第5章习题解答.doc

  • 20页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'第五章数组与指针习题第五章数组与指针习题一、.基本概念与基础知识自测题5.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)的大小是确定的,所谓“不检查数组边界”只是不检查(2)的边界,而(3)的边界是在控制之中的,所以多维数组名作为函数的参数只可以(4)缺省。答案:(1)较低各维的(2)最高维(第一维)(3)较低各维(4)最高维5.1.5指针变量保存了另一变量的(1)值,不可以任意给指针变量赋一个地址值,只能赋给它(2)和(3)的地址。使用变量名来访问变量,是按(4)来直接存取变量称为(5)方式;而借助指针变量取得另一变量的地址,访问该变量称为(6)方式。答案:(1)地址(2)NULL20 第五章数组与指针习题(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];给出指向三维数组第i行第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.2简答题5.2.1物理上,C++是怎样访问数组元素的?请对访问方法作简单介绍。答:物理上,C++语言的下标运算符[]是以指针作为操作数的,a[i]20 第五章数组与指针习题被编译系统解释为*(a+i),即表示为a所指(固定不可变)元素向后第i个元素。无论我们是以下标方式或指针方式存取数组元素时,系统都是转换为指针方法实现。这样做对多维数组尤其方便。5.2.2什么是回溯算法?答:回溯法是对枚举法的一种改进。回溯法的基本思想是,通过对问题的分析找出解决问题的线索,先在一个局部上找出满足问题条件的局部的解,然后逐步由局部解向整个问题的解的方向试探,若试探成功就得到问题的解,试探失败逐步向后退,改变局部解再向前试探。回溯法能避免枚举法的许多不必要的搜索,使问题比较快地得到解决。5.2.3用数组名作为函数的参数时,可否加上数组的长度?如果需要加则怎样加?为什么?答:被调函数中作为形式参数的一维数组不需要说明长度,即使说明了大小也不起作用,因为C++只传递数组首地址,而对数组边界不加检查。5.2.4需要编写一个对多维数组通用的算法(即各维的大小未定),怎样才能把实参多维数组的信息全部传递到函数中去?答:最佳方法是用函数模板,多维数组用模板类型参数传递,各维的大小作为参数传递。也可以用一维数组加各维的大小都作为参数传递。5.2.5解释运算符“*”和“&”的作用,运算符“.”和“->”的作用。答:在应用指针变量时,“*”是间接引用(dereference)运算符,作用于一个指针类型的变量,访问该指针所指向的内存数据。因结果是内存中可寻址的数据。“&”是取地址运算符,作用于内存中一个可寻址的数据(如:变量,对象和数组元素等等),操作的结果是获得该数据的地址。运算符“.”和“->”是成员访问运算符(MemberAccessOprator)。在对象或结构外部去访问公有的数据成员或函数成员时,是在对象名后加“.”(点操作符),再加成员函数名或函数名就可以了。但是这些成员必须是公有的成员,只有公有成员才能在对象的外面对它进行访问。当用指向对象和结构变量的指针访问其公有成员时,则只要在指针变量名后加“->”(箭头操作符),再加公有成员名就可以了。5.2.6什么是this指针?简述它的作用。答:当我们在对象的外部访问该对象的公有成员时,必须指明是哪一个对象。但是当我们用对象的成员函数来访问本对象的成员时,在成员函数中只要给出成员名就可以实现对该对象成员的访问。但同一个类创建的多个对象共用同一份成员函数的拷贝。既然是同一份拷贝,那么成员函数又怎么知道是取哪一个对象的成员数据呢?其实每一个对象有一个隐藏的this指针,它始终指向该对象,并将该指针作为一个参数自动传递给该成员函数。这就是说,成员操作符总是要使用的,只不过在对象内是隐式的,即在对象内省略了this指针。5.2.7指针变量与整型量的加减运算代表什么意义?答:指针变量与整型量的加减表示移动指针,以指向当前目标前面或后面的若干个位置的目标。指针与整型量i的加减等于指针值(地址)与i*sizeof(目标类型)积的加减,得出新的地址。5.2.8设a为数组名,那么a++是否合法?为什么?答:非法。因为a是指针常量。20 第五章数组与指针习题5.2.9指针作为函数的参数时,它传递的是什么?实参要用什么?而使用引用时实参要用什么?何时只能用指针而不能用引用?答:是地址,是指针所指向的变量或对象的内存首地址,在物理上讲我们传的是指针的值,与传其它变量是没有差异的,函数获得的是另一个变量的地址,在逻辑上讲我们是把另一个变量的地址传过去了,可以看作传地址。实参要用变量或对象的地址。而使用引用时实参要用变量或对象本身。实参为数组时,只能用指针而不能用引用,因为数组的引用不存在。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);20 第五章数组与指针习题intmain(){intmiddle[6*3],result[6*4];//注意写作6*3等可清楚看出矩阵的行列intmatrix1[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;20 第五章数组与指针习题intatoi(chars[]){inttemp=0,f=1,i=0;while(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<20 第五章数组与指针习题usingnamespacestd;intmain(){int*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;//未找到返回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);20 第五章数组与指针习题if(*temp1==0)returntemp;//找到子串返回}}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--;20 第五章数组与指针习题}returns;}char*itoa(intn,char*string){char*temp=string;if(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;}char*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<<"输出数字串:"<中定义一个日期时间的结构:20 第五章数组与指针习题structtm{inttm_sec;//秒inttm_min;//分inttm_hour;//时inttm_mday;//日inttm_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利用以上资源,重新设计一个日期时间类(DataTime),要求定义对象时取当前时间进行初始化,显示时重取显示时刻的时间并显示出来。解:#include#includeusingnamespacestd;classdatatime{tm*timedata;longallsecond;char*tmp;public:datatime(){time(&allsecond);timedata=localtime(&allsecond);tmp=asctime(timedata);cout<>ch;if(ch=="y"||"Y")dt.gettime();return0;}5.11完善自定义字符串类mystring,函数包括:构造函数、拷贝构造函数、析构函数,并重载运算符[],=(分别用mystring和C字符串拷贝),+(strcat),+=,<,==(strcmp)。解:此例既是对第4章的复习也是一个提高。拷贝构造函数的应用请参阅4.4.2节末尾两项说明,本例形参使用引用,仅在返回时调用了拷贝构造函数。运算符的重载请参阅4.5节。#includeusingnamespacestd;constintn=256;classmystring{charstr[n];//存放字符串的数组容器intmaxsize;//最大可用元素数,可防止数组出界,提高健壮性intlast;//已用元素最大下标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&);};mystringmystring::operator=(mystring&ms){last=-1;do{last++;str[last]=ms.str[last];}while(lastusingnamespacestd;constintn=256;classmystring{charstr[n];//存放字符串的数组容器intmaxsize;//最大可用元素数,可防止数组出界,提高健壮性intlast;//已用元素最大下标public:mystring(){last=-1;maxsize=n;str[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(){inti=0,j=last-1;chartemp;while(j>i){//注意此处,从串两头同时向中间移动,重合或交错时停止temp=str[i];//头尾交换str[i]=str[j];str[j]=temp;i++;j--;20 第五章数组与指针习题}}intmystring::strchr(charc){inti;for(i=0;i!=last;i++)if(str[i]==c)returni;return-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