文档库 最新最全的文档下载
当前位置:文档库 › 课后习题答案

课后习题答案

第一章 C++基础知识习题
1.1 判断下列标识符的合法性。
sin book 5arry _name Example2.1 main
$1 class_cpp a3 x*y my name

答:合法的:sin book _name main class_cpp a3
非法的:5arry Example2.1 $1 x*y my name
1.2 假定有下列变量:
int a=3,b=5,c=0;
float x=2.5,y=8.2,z=1.4;
char ch1=’a’,ch2=’5’,ch3=’0’,ch4;
求下列表达式的值,以及运算后表达式所涉及的各变量的值。
x+(int)y%a x=z*b++,b=b*x,b++ ch4=ch3-ch2+ch1
int(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.5
x=z*b++,b=b*x,b++ 值为:42,x为7,b为43
ch4=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) 值为:6

1.3 判断下列哪些是常量,哪些是变量。
"China" const int n=10; int m=5; 'a' char ch='a'
int array[5]={1,2,3,4,5}; char s[]="Hello";

答:"China" 文字常量
const int n=10; 常变量
int m=5; 变量
'a' 文字常量
char ch='a' 变量
int array[5]={1,2,3,4,5}; 变量
char s[]="Hello"; 变量

1.4 将下列算式或叙述用C++表达式描述。
(1)
(2) (x+y)/((x-y)*ay)
(3) 位于原点为圆心,a, b为半径的圆环中的点坐标。
(4) 。
(5) 并且字符ch不为'\0'。

答: 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!='\0')

1.6 设有语句:
int a, b;
float x,y;
char ch1,ch2,ch3;
cin>>a>>b>>x>>y>>ch1;
ch2=cin.get();
cin>>ch3;
若从键盘输入:
3 2 1.8 7 a b c
执行后各变量取值如何?注意abc三字符两两间有空格。

答:a是3,b是2,x是1.8,y是7,ch1是’a’,ch2是空格,ch3是’b’。

1.7 设有语句:
int a,b,c,d;
cin>>oct>>a>>b>>hex>>c>>dec>>d;
若从键盘输入:
23 23 23 23
执行后各变量的值用十进制表示各是多少?

答:a:19,b:19,c:35,d:23
1.8 对于习题1.7,若执行:
cout<显示结果是什么?

答:19 0x13 043
第二章 基本控制结构程序设计习题
一.基本概念与基础知识自测题
2.1 程序阅读题
2.1.1 设有说明:
int a=3, b=100;
下面的循环语句执行 (1) 次,执行后a、b的值分别为 (2) 、 (3) 。
while(b/a>5){
if(b-a>25) a++;
else b/=a;
}

解答:
本题检查学生整除的概念。跟踪:
a b b/a 循环次数 b-a
3 100 33 1 97
4 100 25 2 96
5 100 20 3 95
… … … … …
15 100 6 13 85
16 100 6 14 84
17 100 5 停
(1)14
(2)17
(3)100

2.1.2 设有说明:
int x,y,n,k;
下面程序段的功能是备选答案中的

(1) ,当n=10,x=10打印结果是 (2) 。
cin>>x>>n;
k=0;
do{
x/=2;
k++;
}while(ky=1+x;
k=0;
do{
y=y*y;
k++;
}while(kcout<备选答案:
A. B. C. D.
解答:
第一个循环使x成为: ;y成为: ;第二个循环使y成为: ;
(1)B
考虑整除,当x连除4次2以后即为0,所以: 为0
(2)1

2.1.3 请看如下程序段:
if(num==1) cout<<”Alpha”;
else if(num==2) cout<<”Bata”;
else if(num==3) cout<<”Gamma”;
else cout<<”Delta”;
当num的值分别为1、2、3时,上面程序段的输出分别为(1) 、(2) 、(3) 。

解答:
检查条件语句与字符串输出概念:
(1)Alpha
(2)Bata
(3)Gamma

2.1.4 执行下面程序段后,m和k的值分别为 (1) 、 (2) 。
int m,k;
for(k=1,m=0;k<=50;k++){
if(m>=10) break;
if(m%2==0){
m+=5;
continue;
}
m-=3;
}

解答:注意continue语句的使用
初值 m=0 k=1
第1次循环后 m=5 k=2
第2次循环后 m=2 k=3
第3次循环后 m=7 k=4
第4次循环后 m=4 k=5
第5次循环后 m=9 k=6
第6次循环后 m=6 k=7
第7次循环后 m=11 k=8
第8次循环 m=11结束 k=8,k++未做
(1)11
(2)8
第三章 函数习题
一.基本概念与基础知识自测题
3.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)编译
(3)全局生存期
(4)全0

3.1.4局部变量存储在 (1) 区,在 (2) 时候建立,生存期为(3) ,如定义时未显式初始化,则其初值为 (4) 。
答案:
(1)栈
(2)在函数或块开始执行时
(3)函数或块的执行期
(4)随机值

3.1.5 编译预处理的作用是 (1) ,预处理指令的标志是 (2) 。多文件系统中,程序由 (3) 来管理,用户自定义头文件中通常定义一些 (4) 。
答案:
(1)将源程序文件进行处理,生成一个中间文件,编译系统对此中间文件进行编译并生成目标代码
(2)#
(3)工程文件
(4)用户构造的数据类型(如枚举类型),外部变量,外部函数、常量和内联函数等具有一定通用性或常用的量

3.1.6 设有函数说

明如下:
f(int x, int y){ return x%y+1; }
假定a=10,b=4,c=5,下列语句的执行结果分别是 (1) 和 (2) 。
(1) cout<答案:
(1)4
(2)5

3.1.7下列程序的输出结果分别为 (1) 和 (2) 。
(1)
#include
using namespace std;
int a,b;
void f(int j){
static int i=a;
int m,n;
m=i+j; i++; j++; n=i*j; a++;
cout<<"i="<cout<<"m="<}
int main(){
a=1; b=2;
f(b); f(a);
cout<<"a="<return 0;
}
答案:
i=2 j=3 m=3 n=6
i=3 j=3 m=4 n=9
a=3 b=2
(2)
#include
using namespace std;
float sqr(float a){return a*a;}
float p(float x,int n){
cout<<"in-process:"<<"x="<if(n==0) return 1;
else if(n%2!=0) return x*sqr(p(x,n/2));
else return sqr(p(x,n/2));
}
int main(){
cout<return 0;
}
答案:
in-process:x=2 n=13
in-process:x=2 n=6
in-process:x=2 n=3
in-process:x=2 n=1
in-process:x=2 n=0
8192
图解递归,共五层,f是回归时产生:
x n f
2 13 8192 f=x*sqr(下一层的f)
2 6 64 f=sqr(下一层的f)
2 3 8 f=x*sqr(下一层的f)
2 1 2 f=x*sqr(下一层的f)
2 0 1 f=1


3.2 简答题
3.2.1 函数的实参和形参怎样对应?实参和形参数目必须一致吗?什么情况下可以不同?
答:实参和形参的个数和排列顺序应一一对应,并且对应参数应类型匹配(赋值兼容),当有缺省参数时可以不同。

3.2.2 函数和内联函数的执行机制有何不同?定义内联函数有何意义?又有何要求?
答:内联函数的调用机制与一般函数不同,编译器在编译过程中遇到inline时,为该函数建立一段代码,而后在每次调用时直接将该段代码嵌入到调用函数中,从而将函数调用方式变为顺序执行方式,这一过程称为内联函数的扩展或内联。内联函数的实质是牺牲空间来换取时间。因inline指示符对编译器而言只是一个建议,编译器也可以选择忽略该建议,内联函数只适用于功能简单,代码短小而又被重复使用的函数。函数体中包含复杂结构控制语句,如switch、复杂if嵌套、while语句等,以及无法内联展开的递归函数,都不能定义为内联函数,即使定义,系统也将作为一般函数处理。

3.2.3 全局变量和全局静态变量的区别在哪里?为什么提倡尽量使用局部变量?
答:有static修饰的全局变量只能在定义它的文件中可见,在其他文件中不可见,而非静态的全局变量则可以被其他程序文件访问,但使用前必须用extern说明。
局部变量具有局部作用域使得程序在不同块中可以使用同名变量。这些同名变量各自在自己的作用域中可见,在其它地方不可见。所以提倡尽量使用局部变



3.2.4 函数重载的作用是什么?满足什么条件的函数才可以成为重载函数?重载函数在调用时是怎样进行对应的?
答:函数重载可以定义几个功能相似,而参数类型不同使用相同的函数名的函数,以适应不同情况下自动选用不同函数进行操作。函数重载的好处在于,可以用相同的函数名来定义一组功能相同或类似的函数,程序的可读性增强。
在定义重载函数时必须保证参数类型不同,仅仅返回值类型不同是不行的。
当某个函数中调用到重载函数时,编译器会根据实参的类型去对应地调用相应的函数。匹配过程按如下步骤进行:
(1)如果有严格匹配的函数,就调用该函数;
(2)参数内部转换后如果匹配,调用该函数;
(3)通过用户定义的转换寻求匹配。

3.2.5 多文件结构的程序是如何进行管理并运行的?采用多文件结构有什么好处?
答:多文件结构通过工程进行管理,在工程中建立若干用户定义的头文件.h和源程序文件.cpp。头文件中定义用户自定义的数据类型,所有的程序实现则放在不同的源程序文件中。编译时每个源程序文件单独编译,如果源程序文件中有编译预处理指令,则首先经过编译预处理生成临时文件存放在内存,之后对临时文件进行编译生成目标文件.obj,编译后临时文件撤销。所有的目标文件经连接器连接最终生成一个完整的可执行文件.exe。
多文件结构管理程序的好处是十分明显的。首先,可以避免重复性的编译,如果修改了个别函数,那么只需将这些函数所在的文件重新编译即可;其次,将程序进行合理的功能划分后,更容易设计、调试和维护;另外,通常把相关函数放在一个文件中,这样形成一系列按照功能分类的文件,便于为其他程序文件使用。

3.2.6 宏定义与常量定义从作用及效果上看是一样的,二者是否完全相同?
答:完全不同。不带参宏定义与const说明符定义常量从效果上看是一样的,但它们的机制不同。首先宏定义是在预处理阶段完成,而const定义则是在编译阶段实现。其次宏定义只是一种简单的字符串替代,不会为字符串分配内存单元,替代过程也不作语法检查,即使指令中的常量字符串不符合常量要求,预处理的替代过程也照样按指令给出的格式进行。而const定义则是象定义一个变量一样定义一个常量标识符,系统要按照类型要求为该标识符分配内存单元,同时在将常量放入单元时进行类型检查,如果类型不匹配,类型相容的会进行系统的类型转换,不相容的则要提示错误。

第五章 数组与指针习题
一、.基本概念与基础知识自测题
5.1 填充题
5.1.1 数组定义时有三个要素:

数组名,数组元素的 (1) 和数组元素的 (2) 。按元素在数组中的位置进行访问,是通过 (3) 进行的,称为 (4) 或 (5) 访问。为了使数组声明中数组的大小修改更为方便,总是将 (6) 用于声明数组长度。
答案:(1)类型
(2)数量
(3)下标运算符
(4)下标
(5)索引
(6)常变量

5.1.2 C/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)*u

5.1.4 对于多维数组, (1) 的大小是确定的,所谓“不检查数组边界”只是不检查 (2) 的边界,而 (3) 的边界是在控制之中的,所以多维数组名作为函数的参数只可以 (4) 缺省。
答案:(1)较低各维的
(2)最高维(第一维)
(3)较低各维
(4)最高维

5.1.5 指针变量保存了另一变量的 (1)值,不可以任意给指针变量赋一个地址值,只能赋给它 (2) 和 (3) 的地址。使用变量名来访问变量,是按 (4) 来直接存取变量称为 (5) 方式;而借助指针变量取得另一变量的地址,访问该变量称为 (6) 方式。
答案:(1)地址
(2)NULL
(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 有一个三维数组:
int z3d[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]被编译系统解释为*(a+i),即表示为a所指(固定不可变)元素向后第i个元素。无论我们是以下标方式或指针方式存取数组元素时,系统都是转换为指针方法实现。这样做对多维数组尤其方便。

5.2.2 什么是回溯算法?
答:回溯法是对枚举法的一种改进。回溯法的基本思想是,通过对问题的分析找出解决问题的线索,先在一个局部上找出满足问题条件的局部的解,然后逐步由局部解向整个问题的解的方向试探,若试探成功就得到问题的解,试探失败逐步向后退,改变局部解再向前试探。回溯法能避免枚举法的许多不必要的搜索,使问题比较快地得到解决。

5.2.3 用数组名作为函数的参数时,可否加上数组的长度?如果需要加则怎样加?为什么?
答:被调函数中作为形式参数的一维数组不需要说明长度,即使说明了大小也不起作用,因为C++只传递数组首地址,而对数组边界不加检查。

5.2.4 需要编写一个对多维数组通用的算法(即各维的大小未定),怎样才能把实参多维数组的信息全部传递到函数中去?
答:最佳方法是用函数模板,多维数组用模板类型参数传递,各维的大小作为参数传递。也可以用一维数组加各维的大小都作为参数传递。

5.2.5 解释运算符“*”和“&”的作用,运算符“.”和“->”的作用。
答:在应用指针变量时,“*”是间接引用(dereference)运算符,作用于一个指针类型的变量,访问该指针所指向的内存数据。因结果是内存中可寻址的数据。“&”是取地址运算符,作用于内存中一个可寻址的数据(如:变量,对象和数组元素等等),操作的结果是获得该数据的地址。
运算符“.”和“->”是成员访问运算符(Member Access Oprator)。在对象或结构外部去访问公有的数据成员或函数成员时,是在对象名后加“.”(点操作符),再加成员函数名或函数名就可以了。但是这些成员必须是公有的成员,只有公有成员才能在对象的外面对它进行访问。当用指向对象和

结构变量的指针访问其公有成员时,则只要在指针变量名后加 “->” (箭头操作符),再加公有成员名就可以了。

5.2.6 什么是this指针?简述它的作用。
答:当我们在对象的外部访问该对象的公有成员时,必须指明是哪一个对象。但是当我们用对象的成员函数来访问本对象的成员时,在成员函数中只要给出成员名就可以实现对该对象成员的访问。但同一个类创建的多个对象共用同一份成员函数的拷贝。既然是同一份拷贝,那么成员函数又怎么知道是取哪一个对象的成员数据呢?其实每一个对象有一个隐藏的this指针,它始终指向该对象,并将该指针作为一个参数自动传递给该成员函数。这就是说,成员操作符总是要使用的,只不过在对象内是隐式的,即在对象内省略了this指针。

5.2.7 指针变量与整型量的加减运算代表什么意义?
答:指针变量与整型量的加减表示移动指针,以指向当前目标前面或后面的若干个位置的目标。指针与整型量i的加减等于指针值(地址)与i*sizeof(目标类型)积的加减,得出新的地址。

5.2.8 设a为数组名,那么a++是否合法?为什么?
答:非法。因为a是指针常量。

5.2.9 指针作为函数的参数时,它传递的是什么?实参要用什么?而使用引用时实参要用什么?何时只能用指针而不能用引用?
答:是地址,是指针所指向的变量或对象的内存首地址,在物理上讲我们传的是指针的值,与传其它变量是没有差异的,函数获得的是另一个变量的地址,在逻辑上讲我们是把另一个变量的地址传过去了,可以看作传地址。实参要用变量或对象的地址。而使用引用时实参要用变量或对象本身。实参为数组时,只能用指针而不能用引用,因为数组的引用不存在。

5.2.10 指针作为函数的返回值时,应该注意什么?
答:指针指向的数据的生命期必须不仅仅在函数域中,函数消亡后,数据仍然存在。如果返回的指针,它所指的变量或对象已消亡,则该返回值无意义,这一点必须十分小心。总之直接使用指针不管是作为参数还是返回值,都要注意安全性。

5.2.11 设有语句
char *ps=”It’s a book.”;
是否建立了一个字符串,并把”it’s a book.”作为其初值?随后又有语句:
*ps=”It’s a car”;
这又代表什么?是否正确。
答:没有建立字符串,只是让ps指向一个放在代码区中的特殊字符串,而该字符串所在内存是不可写的。后一条语句要求把字符串赋给不可写的字符串空间是错的。

二、编程与综合练习题

5.6 有如下定义:
int ival=60021;
int *ip;
double *dp;
下面哪些赋值非法或可能带来错误,并加以讨论。
ival=*ip; ival=ip; *ip=iv

al; ip=ival; *ip=&ival;
ip=&ival; dp=ip; dp=*ip; *dp=*ip;
解:ival=*ip; 错,未确定指针ip初值,用随机内存地址中的数据给ival赋值是危险的。但语法对。
ival=ip; 错,赋值类型错,指针型不能赋给整型。
*ip=ival; 错,未确定指针ip初值,用ival给随机内存赋值是危险的。但语法对。
ip=ival; 错,赋值类型错,整型不能赋给指针型。
*ip=&ival; 错,赋值类型错,地址(指针型)不能赋给整型。
ip=&ival; 对,地址赋给指针型。
dp=ip; 错,整型指针不能赋给双精度指针。
dp=*ip; 错,赋值类型错,整型不能赋给指针型。
*dp=*ip; 对,赋值类型转换


相关文档
相关文档 最新文档