C++Primer中文版习题及详细分析.docx
《C++Primer中文版习题及详细分析.docx》由会员分享,可在线阅读,更多相关《C++Primer中文版习题及详细分析.docx(36页珍藏版)》请在冰点文库上搜索。
C++Primer中文版习题及详细分析
习题
查看所用的编译器文档,了解它所用的文件命名规范。
编译并运行本节的main
程序。
【解答】
一般而言,C++编译器要求待编译的程序保存在文件中。
C++程序中一般涉及两
类文件:
头文件和源文件。
大多数系统中,文件的名字由文件名和文件后缀(又
称扩展名)组成。
文件后缀通常表明文件的类型,如头文件的后缀可以是.h
或.hpp等;源文件的后缀可以是.cc或.cpp等,具体的后缀与使用的编译器有
关。
通常可以通过编译器所提供的联机帮助文档了解其文件命名规范。
习题
修改程序使其返回-1。
返回值-1通常作为程序运行失败的指示器。
然而,系统
不同,如何(甚至是否)报告main函数运行失败也不同。
重新编译并再次运行
程序,看看你的系统如何处理main函数的运行失败指示器。
【解答】
笔者所使用的Windows操作系统并不报告main函数的运行失败,因此,程序返
回-1或返回0在运行效果上没有什么区别。
但是,如果在DOS命令提示符方式
下运行程序,然后再键入echo%ERRORLEVEL%命令,则系统会显示返回值-1。
习题
编一个程序,在标准输出上打印“Hello,World”。
#include
#include""
usingnamespacestd;
intmain()
{system("CLS");
cout<<"Hello,World!
"<return0;
}
习题
我们的程序利用内置的加法操作符“+”来产生两个数的和。
编写程序,使用乘
法操作符“*”产生两个数的积。
#include
#include""
usingnamespacestd;
intmain()
{system("CLS");
cout<<"Entertwonumbers:
"<intv1,v2;
cin>>v1>>v2;
cout<<"Theproductof"<return0;
}
习题
我们的程序使用了一条较长的输出语句。
重写程序,使用单独的语句打印每一
个操作数。
#include
#include""
usingnamespacestd;
intmain()
{
system("CLS");
cout<<"Entertwonumbers:
"<intv1,v2;
cin>>v1>>v2;
cout<<"Thesumof";
cout<cout<<"and";
cout<cout<<"is";
cout<cout<return0;
}习题
解释下面的程序段:
std:
:
cout<<"Thesumof"<<<"and"<<<"is"<<:
endl;
这段代码合法吗如果合法,为什么如果不合法,又为什么
【解答】
这段代码不合法。
注意,第1、2、4行的末尾有分号,表示这段代码包含三条语句,即第1、2行
各为一个语句,第3、4行构成一个语句。
“<<”为二元操作符,在第2、3两
条语句中,第一个“<<”缺少左操作数,因此不合法。
在第2、3行的开头加上“std:
:
cout”,即可更正。
习题
编译有不正确嵌套注释的程序。
【解答】
由注释对嵌套导致的编译器错误信息通常令人迷惑。
例如,在笔者所用的编译
器中编译节中给出的带有不正确嵌套注释的程序:
#include
/*
*commentpairs/**/cannotnest.
*"cannotnest"isconsideredsourcecode,
*asistherestoftheprogram
*/
intmain()
{
return0;
}
编译器会给出如下错误信息:
errorC2143:
syntaxerror:
missing';'before'<'
errorC2501:
'include':
missingstorage-classortypespecifiers
warningC4138:
'*/'foundoutsideofcomment(第6行)
errorC2143:
syntaxerror:
missing';'before'{'(第8行)
errorC2447:
'{':
missingfunctionheader(old-styleformallist)(第
8行)
习题
指出下列输出语句哪些(如果有)是合法的。
std:
:
cout<<"/*";
std:
:
cout<<"*/";
std:
:
cout<*"*/"*/;
预测结果,然后编译包含上述三条语句的程序,检查你的答案。
纠正所遇到的
错误。
【解答】
第一条和第二条语句合法。
第三条语句中<<操作符之后至第二个双引号之前的部分被注释掉了,导致<<操
作符的右操作数不是一个完整的字符串,所以不合法。
在分号之前加上一个双
引号即可更正。
习题
下列循环做什么sum的最终值是多少
intsum=0;
for(inti=-100;i<=100;++i)
sum+=i;
【解答】
该循环求-100~100之间所有整数的和(包括-100和100)。
sum的最终值是0。
习题
用for循环编程,求从50~100的所有自然数的和。
然后用while循环重写该程
序。
【解答】
用for循环编写的程序如下:
#include
#include""
intmain()
{
intsum=0;
system("CLS");
for(inti=50;i<=100;++i)
sum+=i;
std:
:
cout<<"Sumof50to100inclusiveis"
<:
endl;
return0;
}
用while循环编写的程序如下:
#include
#include""
usingnamespacestd;
intmain()
{
intsum=0,i=50;
system("CLS");
while(i<=100)
{
sum+=i;
i++;
}
cout<<"Sumof50to100inclusiveis"<return0;
}
习题
用while循环编程,输出10~0递减的自然数。
然后用for循环重写该程序。
【解答】
用while循环编写的程序如下:
#include
#include""
usingnamespacestd;
intmain()
{inti=10;
system("CLS");
while(i>=0)
{
cout<
i--;
}
cout<return0;
}
用for循环编写的程序如下:
#include
#include""
usingnamespacestd;
intmain()
{system("CLS");
for(inti=10;i>=0;i--)
{
cout<
}
cout<return0;
}
习题
对比前面两个习题中所写的循环。
两种形式各有何优缺点
【解答】
在for循环中,循环控制变量的初始化和修改都放在语句头部分,形式较简洁,
且特别适用于循环次数已知的情况。
在while循环中,循环控制变量的初始化
一般放在while语句之前,循环控制变量的修改一般放在循环体中,形式上不
如for语句简洁,但它比较适用于循环次数不易预知的情况(用某一条件控制
循环)。
两种形式各有优点,但它们在功能上是等价的,可以相互转换。
习题
编译器不同,理解其诊断内容的难易程度也不同。
编写一些程序,包含本小节
“再谈编译”部分讨论的那些常见错误。
研究编译器产生的信息,这样你在编
译更复杂的程序遇到这些信息时不会陌生。
【解答】
对于程序中出现的错误,编译器通常会给出简略的提示信息,包括错误出现的
文件及代码行、错误代码、错误性质的描述。
如果要获得关于该错误的详细信
息,一般可以根据编译器给出的错误代码在其联机帮助文档中查找。
习题
如果输入值相等,本节展示的程序将产生什么问题
【解答】
sum的值即为输入值。
因为输入的v1和v2值相等(假设为x),所以lower和
upper相等,均为x。
for循环中的循环变量val初始化为lower,从而val<=upper
为真,循环体执行一次,sum的值为val(即输入值x);然后val加1,val的
值就大于upper,循环执行结束。
习题
用两个相等的值作为输入编译并运行本节中的程序。
将实际输出与你在习题
中所做的预测相比较,解释实际结果和你预计的结果间的不相符之处。
【解答】
运行节中给出的程序,输入两个相等的值(例如3,3),则程序输出为:
Sumof3to3inclusiveis3
与习题中给出的预测一致。
习题
编写程序,输出用户输入的两个数中的较大者。
#include
#include""
usingnamespacestd;
intmain()
{
system("CLS");
cout<<"Entertwonumbers:
"<intv1,v2;
cin>>v1>>v2;
if(v1>=v2)
cout<<"Thebiggernumberis:
"<else
cout<<"Thebiggernumberis:
"<return0;
}
习题
编写程序,要求用户输入一组数。
输出信息说明其中有多少个负数。
#include
#include""
usingnamespacestd;
intmain()
{
intamount=0,value;
system("CLS");
<return0;
}
习题
编写程序,读入几个具有相同ISBN的交易,输出所有读入交易的和。
#include
#include""
#include""
usingnamespacestd;
intmain()
{
Sales_itemtotal,trans;
system("CLS");
cout<<"Entertransactions:
"<if(cin>>total)
{
while(cin>>trans)
if(trans))<return-1;
}
(d)-10e-2
【解答】
(a)int型
(b)unsignedint型
(c)double型
(d)double型
习题
下列哪些(如果有)是非法的
(a)"WhogoeswithF\145rgus\012"
(b)(c)"two"L"some"
(d)1024f(e)
(f)"multipleline
comment"
【解答】
(c)非法。
因为字符串字面值与宽字符串字面值的连接是未定义的。
(d)非法。
因为整数1024后面不能带后缀f。
(e)非法。
因为浮点字面值不能带后缀U。
(f)非法。
因为分两行书写的字符串字面值必须在第一行的末尾加上反斜线。
习题
使用转义字符编写一段程序,输出2M,然后换行。
修改程序,输出2,跟着一
个制表符,然后是M,最后是换行符。
【解答】
输出2M、然后换行的程序段:
.
return0;
}
【解答】
global_str和local_str的初始值均为空字符串,global_int的初始值为0,
local_int没有初始值。
习题
解释下列例子中name的意义:
externstd:
:
stringname;
std:
:
stringname("exercise");
externstd:
:
stringname("exercise");
【解答】
第一条语句是一个声明,说明std:
:
string变量name在程序的其他地方定义。
第二条语句是一个定义,定义了std:
:
string变量name,并将name初始化为
"exercise"。
第三条语句也是一个定义,定义了std:
:
string变量name,并将name初始化为
"exercise",但这个语句只能出现在函数外部(即,name是一个全局变量)。
习题
下列程序中j的值是多少
inti=42;
intmain()
{
inti=100;
intj=i;
.
}
【解答】
j的值是100。
j的赋值所使用到的i应该是main函数中定义的局部变量i,因
为局部变量的定义会屏蔽全局变量的定义。
习题
下列程序段将会输出什么
inti=100,sum=0;
for(inti=0;i!
=10;++i)
sum+=i;
std:
:
cout<
:
endl;
【解答】
输出为:
10045
for语句中定义的变量i,其作用域仅限于for语句内部。
输出的i值是for语
句之前所定义的变量i的值。
习题
下列程序合法吗
intsum=0;
for(inti=0;i!
=10;++i)
sum+=i;
std:
:
cout<<"Sumfrom0to"<
<<"is"<:
endl;
【解答】
不合法。
因为变量i具有语句作用域,只能在for语句中使用,输出语句中
使用i属非法。
习题
下列程序段虽然合法,但是风格很糟糕。
有什么问题呢怎样改善
for(inti=0;i<100;++i)
.对象上的操作
private:
std:
:
stringcountry_number;
std:
:
stringcity_number;
std:
:
stringphone_number;
};
(b)地址
classAddress{
public:
对象上的操作
private:
std:
:
stringcountry;
std:
:
stringcity;
std:
:
stringstreet;
std:
:
stringnumber;
};
(c)员工或公司
classEmployee{
public:
.对象上的操作
private:
std:
:
stringID;
std:
:
stringname;
charsex;
Addressaddr;
Tel_numbertel;
};
classCompany{
public:
.对象上的操作
private:
std:
:
stringname;
Addressaddr;
Tel_numbertel;
};
(d)某大学的学生
classStudent{
public:
.对象上的操作
private:
std:
:
stringID;
std:
:
stringname;
charsex;
std:
:
stringdept;ET2003)中,在Project菜
单中选择Properties菜单项,在Configuration
Properties→C/C++→General→WarningLevel中可以选择警告级别。
习题
用适当的using声明,而不用std:
:
前缀,访问标准库中的名字,重新编写
节的程序,计算一给定数的给定次幂的结果。
#include
#include""
usingnamespacestd;
intmain()
{
intbase,exponent;
longresult=1;
system("CLS");
cout<<"Enterbaseandexponent:
"<cin>>base>>exponent;
if(exponent<0)
{
cout<<"Exponentcan'tbesmallerthan0"<return-1;
}
if(exponent>0)
{
for(intcnt=1;cnt<=exponent;cnt++)
result*=base;
}
cout<
"<return0;
}
习题
什么是默认构造函数
【解答】
默认构造函数(defaultconstructor)就是在没有显式提供初始化式时调用的
构造函数。
它由不带参数的构造函数,或者为所有形参提供默认实参的构造函
数定义。
如果定义某个类的变量时没有提供初始化式,就会使用默认构造函数。
如果用户定义的类中没有显式定义任何构造函数,编译器就会自动为该类生成
默认构造函数,称为合成的默认构造函数(synthesizeddefaultconstructor)。
习题
列举出三种初始化string对象的方法。
【解答】
(1)不带初始化式,使用默认构造函数初始化string对象。
(2)使用一个已存在的string对象作为初始化式,将新创建的string对象初
始化为已存在对象的副本。
(3)使用字符串字面值作为初始化式,将新创建的string对象初始化为字符串
字面值的副本。
习题
s和s2的值分别是什么
strings;
intmain(){
strings2;
}
【解答】
s和s2的值均为空字符串。
习题
编写程序实现从标准输入每次读入一行文本。
然后改写程序,每次读入一个单
词。
#include
#include
#include""
usingnamespacestd;
intmain()
{
stringline;
system("CLS");
while(getline(cin,line))
cout<return0;
}
修改后程序如下:
<elseif(s1>s2)
cout<<"\""<<<"\""<else
cout<<"\""<<<"\""<return0;
}
测试两个string对象的长度是否相等的程序:
#include
#include
usingnamespacestd;
intmain()
{
strings1,s2;
cout<<"Entertwostrings:
"<cin>>s1>>s2;
string:
:
size_typelen1,len2;
len1=();
len2=();
if(len1==len2)
cout<<"Theyhavesamelength."<elseif(len1>len2)
cout<<"\""<<<"\""<else
cout<<"\""<<<"\""<return0;
}
习题
编一个程序,从标准输入读取多个string对象,把它们连接起来存放到一个更
大的string对象中,并输出连接后的string对象。
接着,改写程序,将连接
后相邻string对象以空格隔开。
【解答】
#include
#include
usingnamespacestd;
intmain()
{
stringresult_str,str;
cout<<"Enterstrings(Ctrl+Ztoend):
"<while(cin>>str)
result_str=result_str+str;
cout<<"Stringequaltotheconcatenationofthesestringsis:
"
<return0;
}
改写后的程序:
#include
#include
usingnamespacestd;
intmain()
{
stringresult_str,str;
cout<<"Enterstrings(Ctrl+Ztoend):
"<cin>>result_str;
while(cin>>str)
result_str=result_str+''+str;
cout<<"Stringequaltotheconcatenationofthesestringsis:
"
<return0;
}
习题
下列程序实现什么功能实现合法吗如果不合法,说明理由。
strings;
cout<