C++ Primer 【第四版】第三章 标准库类型
来源:互联网 发布:宋仲基宋慧乔婚礼知乎 编辑:程序博客网 时间:2024/05/01 13:52
习题3.1
用适当的using声明,而不用std::前缀,访问标准库中的名字,重新编写2.3节的程序,计算一给定数的给定次幂的结果。
【解答】
#include<iostream>
usingstd::cin;
usingstd::cout;
intmain()
{
//局部对象
intbase, exponent;
longresult=1;
//读入底数和指数
cout<< "Enter base and exponent:" << endl;
cin>> base >> exponent;
if(exponent < 0) {
cout<< "Exponent can't be smaller than 0" << endl;
return-1;
}
if(exponent > 0) {
//计算底数的指数次方
for(int cnt = 1; cnt <= exponent; ++cnt)
result*= base;
}
cout<< base
<<" raised to the power of "
<<exponent << ": "
<<result << endl;
return0;
}
习题3.2
什么是默认构造函数?
【解答】
默认构造函数(default constructor)就是在没有显式提供初始化式时调用的构造函数。它由不带参数的构造函数,或者为所有形参提供默认实参的构造函数定义。如果定义某个类的变量时没有提供初始化式,就会使用默认构造函数。如果用户定义的类中没有显式定义任何构造函数,编译器就会自动为该类生成默认构造函数,称为合成的默认构造函数(synthesized default constructor)。
习题3.3
列举出三种初始化string对象的方法。
【解答】
(1)不带初始化式,使用默认构造函数初始化string对象。
(2)使用一个已存在的string对象作为初始化式,将新创建的string 对象初始化为已存在对象的副本。
(3)使用字符串字面值作为初始化式,将新创建的string对象初始化为字符串字面值的副本。
习题3.4
s和s2的值分别是什么?
strings;
intmain() {
strings2;
}
【解答】
s和s2的值均为空字符串。
习题3.5
编写程序实现从标准输入每次读入一行文本。然后改写程序,每次读入一个单
词。
【解答】
//从标准输入每次读入一行文本
#include<iostream>
#include<string>
usingnamespace std;
intmain()
{
stringline;
//一次读入一行,直至遇见文件结束符
while(getline(cin, line))
cout<< line << endl; //输出相应行以进行验证
return0;
}
修改后程序如下:
//从标准输入每次读入一个单词
#include<iostream>
#include<string>
usingnamespace std;
intmain()
{
stringword;
//一次读入一个单词,直至遇见文件结束符
while(cin >> word)
cout<< word << endl; //输出相应单词以进行验证
return0;
}
注意,一般而言,应该尽量避免使用using指示而使用using 声明(参见17.2.4
节),因为如果应用程序中使用了多个库,使用using指示引入这些库中定义
的名字空间,容易导致名字冲突。但本书中的程序都只使用了标准库,没有使
用其他库。使用using指示引入名字空间std 中定义的所有名字不会发生名字
冲突。因此为了使得代码更为简洁以节省篇幅,本书的许多代码中都使用了
using指示using namespace std;来引入名字空间std。另外,本题中并未要求
输出,加入输出是为了更清楚地表示读入的结果。本书后面部分有些地方与此
类似处理,不再赘述。
习题3.6
解释string类型的输入操作符和getline 函数分别如何处理空白字符。
【解答】
string类型的输入操作符对空白字符的处理:读取并忽略有效字符(非空白字
符)之前所有的空白字符,然后读取字符直至再次遇到空白字符,读取终止(该
空白字符仍留在输入流中)。
getline函数对空白字符的处理:不忽略行开头的空白字符,读取字符直至遇到
换行符,读取终止并丢弃换行符(换行符从输入流中去掉但并不存储在string
对象中)。
习题3.7
编一个程序读入两个string对象,测试它们是否相等。若不相等,则指出两个
中哪个较大。接着,改写程序测试它们的长度是否相等,若不相等,则指出两
个中哪个较长。
【解答】
测试两个string对象是否相等的程序:
#include<iostream>
#include<string>
usingnamespace std;
intmain()
{
strings1, s2;
//读入两个string对象
cout<< "Enter two strings:" << endl;
C++Primer(4版)习题解答
41
cin>> s1 >> s2;
//测试两个string对象是否相等
if(s1 == s2)
cout<< "They are equal." << endl;
elseif (s1 > s2)
cout<< "\"" << s1 << "\" is biggerthan"
<<" \"" << s2 << "\"" << endl;
else
cout<< "\"" << s2 << "\" is biggerthan"
<<" \"" << s1 << "\"" << endl;
return0;
}
测试两个string对象的长度是否相等的程序:
#include<iostream>
#include<string>
usingnamespace std;
intmain()
{
strings1, s2;
//读入两个string对象
cout<< "Enter two strings:" << endl;
cin>> s1 >> s2;
//比较两个string对象的长度
string::size_typelen1, len2;
C++Primer(4版)习题解答
42
len1= s1.size();
len2= s2.size();
if(len1 == len2)
cout<< "They have same length." << endl;
elseif (len1 > len2)
cout<< "\"" << s1 << "\" is longerthan"
<<" \"" << s2 << "\"" << endl;
else
cout<< "\"" << s2 << "\" is longerthan"
<<" \"" << s1 << "\"" << endl;
return0;
}
习题3.8
编一个程序,从标准输入读取多个string对象,把它们连接起来存放到一个更
大的string对象中,并输出连接后的string 对象。接着,改写程序,将连接
后相邻string对象以空格隔开。
【解答】
#include<iostream>
#include<string>
usingnamespace std;
intmain()
{
stringresult_str, str;
//读入多个string对象并进行连接
C++Primer(4版)习题解答
43
cout<< "Enter strings(Ctrl+Z to end):" << endl;
while(cin>>str)
result_str= result_str + str;
//输出连接后的string对象
cout<< "String equal to the concatenation of these strings is:"
<<endl << result_str << endl;
return0;
}
改写后的程序:
#include<iostream>
#include<string>
usingnamespace std;
intmain()
{
stringresult_str, str;
//读入多个string对象并进行连接
cout<< "Enter strings(Ctrl+Z to end):" << endl;
cin>> result_str;//读入第一个string对象,放到结果对象中
while(cin>>str)
result_str= result_str + ' ' + str;
//输出连接后的string对象
cout<< "String equal to the concatenation of these strings is:"
<<endl << result_str << endl;
return0;
C++Primer(4版)习题解答
44
}
习题3.9
下列程序实现什么功能?实现合法吗?如果不合法,说明理由。
strings;
cout<< s[0] << endl;
【解答】
该程序段输出string对象s 所对应字符串的第一个字符。
实现不合法。因为s是一个空字符串,其长度为0,因此s[0]是无效的。
注意,在一些编译器(如Microsoft Visual C++ .NET 2003)的实现中,该
程序段并不出现编译错误。
习题3.10
编一个程序,从string对象中去掉标点符号。要求输入到程序的字符串必须含
有标点符号,输出结果则是去掉标点符号后的string对象。
【解答】
#include<iostream>
#include<string>
#include<cctype>
usingnamespace std;
intmain()
{
strings, result_str;
boolhas_punct = false;//用于标记字符串中有无标点
charch;
//输入字符串
C++Primer(4版)习题解答
45
cout<< "Enter a string:" << endl;
getline(cin,s);
//处理字符串:去掉其中的标点
for(string::size_type index = 0; index != s.size(); ++index)
{
ch= s[index];
if(ispunct(ch))
has_punct= true;
else
result_str+= ch;
}
if(has_punct)
cout<< "Result:" << endl << result_str <<endl;
else{
cout<< "No punctuation character in the string?!" << endl;
return-1;
}
return0;
}
习题3.11
下面哪些vector定义不正确?
(a)vector< vector<int> > ivec;
(b)vector<string> svec = ivec ;
(c)vector<string> svec(10,"null");
C++Primer(4版)习题解答
46
【解答】
(b)不正确。因为svec定义为保存string对象的vector 对象,而ivec 是
保存vector <int>对象的vector对象(即ivec 是vector 的vector),二者
的元素类型不同,所以不能用ivec来初始化svec。
习题3.12
下列每个vector对象中元素个数是多少?各元素的值是什么?
(a)vector<int> ivec1;
(b)vector<int> ivec2(10);
(c)vector<int> ivec3(10,42);
(d)vector<string> svec1;
(e)vector<string> svec2(10);
(f)vector<string> svec3(10,"hello");
【解答】
(a)元素个数为0。
(b)元素个数为10,各元素的值均为0。
(c)元素个数为10,各元素的值均为42。
(d)元素个数为0。
(e)元素个数为10,各元素的值均为空字符串。
(f)元素个数为10,各元素的值均为"hello"。
习题3.13
读一组整数到vector对象,计算并输出每对相邻元素的和。如果读入元素个数
为奇数,则提示用户最后一个元素没有求和,并输出其值。然后修改程序:头
尾元素两两配对(第一个和最后一个,第二个和倒数第二个,以此类推),计
算每对元素的和,并输出。
【解答】
//读一组整数到vector对象,计算并输出每对相邻元素的和
C++Primer(4版)习题解答
47
#include<iostream>
#include<vector>
usingnamespace std;
intmain()
{
vector<int>ivec;
intival;
//读入数据到vector对象
cout<< "Enter numbers(Ctrl+Z to end):" << endl;
while(cin>>ival)
ivec.push_back(ival);
//计算相邻元素的和并输出
if(ivec.size() == 0) {
cout<< "No element?!" << endl;
return-1;
}
cout<< "Sum of each pair of adjacent elements in the vector:"
<<endl;
for(vector<int>::size_type ix = 0; ix < ivec.size()-1;
ix= ix + 2) {
cout<< ivec[ix] + ivec[ix+1] << "\t";
if( (ix+1) % 6 == 0) //每行输出6个和
cout<< endl;
}
C++Primer(4版)习题解答
48
if(ivec.size() % 2 != 0) //提示最后一个元素没有求和
cout<< endl
<<"The last element is not been summed "
<<"and its value is "
<<ivec[ivec.size()-1] << endl;
return0;
}
修改后的程序:
//读一组整数到vector对象,计算首尾配对元素的和并输出
#include<iostream>
#include<vector>
usingnamespace std;
intmain()
{
vector<int>ivec;
intival;
//读入数据到vector对象
cout<< "Enter numbers:" << endl;
while(cin>>ival)
ivec.push_back(ival);
//计算首尾配对元素的和并输出
if(ivec.size() == 0) {
cout<< "No element?!" << endl;
return-1;
C++Primer(4版)习题解答
49
}
cout<< "Sum of each pair of counterpart elements in the vector:"
<<endl;
vector<int>::size_typecnt = 0;
for(vector<int>::size_type first = 0, last = ivec.size() - 1;
first< last; ++first, --last) {
cout<< ivec[first] + ivec[last] << "\t";
++cnt;
if( cnt % 6 == 0) //每行输出6个和
cout<< endl;
}
if(first == last) //提示居中元素没有求和
cout<< endl
<<"The center element is not been summed "
<<"and its value is "
<<ivec[first] << endl;
return0;
}
习题3.14
读入一段文本到vector对象,每个单词存储为vector 中的一个元素。把vector
对象中每个单词转化为大写字母。输出vector对象中转化后的元素,每8 个单
词为一行输出。
【解答】
//读入一段文本到vector对象,每个单词存储为vector 中的一个元素。
C++Primer(4版)习题解答
50
//把vector对象中每个单词转化为大写字母。
//输出vector对象中转化后的元素,每8个单词为一行输出
#include<iostream>
#include<string>
#include<vector>
#include<cctype>
usingnamespace std;
intmain()
{
vector<string>svec;
stringstr;
//读入文本到vector对象
cout<< "Enter text(Ctrl+Z to end):" << endl;
while(cin>>str)
svec.push_back(str);
//将vector对象中每个单词转化为大写字母,并输出
if(svec.size() == 0) {
cout<< "No string?!" << endl;
return-1;
}
cout<< "Transformed elements from the vector:"
<<endl;
for(vector<string>::size_type ix = 0; ix != svec.size(); ++ix) {
C++Primer(4版)习题解答
51
for(string::size_type index = 0; index != svec[ix].size();
++index)
if(islower(svec[ix][index]))
//单词中下标为index的字符为小写字母
svec[ix][index]= toupper(svec[ix][index]);
cout<< svec[ix] << " ";
if((ix + 1) % 8 == 0)//每8个单词为一行输出
cout<< endl;
}
return0;
}
习题3.15
下面程序合法吗?如果不合法,如何更正?
vector<int>ivec;
ivec[0]= 42;
【解答】
不合法。因为ivec是空的vector 对象,其中不含任何元素,而下标操作只
能用于获取已存在的元素。
更正:将赋值语句改为语句ivec.push_back(42);。
习题3.16
列出三种定义vector对象的方法,给定10 个元素,每个元素值为42。指出是
否还有更好的实现方法,并说明为什么。
【解答】
方法一:
vector<int>ivec(10, 42);
C++Primer(4版)习题解答
52
方法二:
vector<int>ivec(10);
for(ix = 0; ix < 10; ++ix)
ivec[ix]= 42;
方法三:
vector<int>ivec(10);
for(vector<int>::iterator iter = ivec.begin();
iter!= ivec.end(); ++iter)
*iter= 42;
方法四:
vector<int>ivec;
for(cnt = 1; cnt <= 10; ++cnt)
ivec.push_back(42);
方法五:
vector<int>ivec;
vector<int>::iteratoriter = ivec.end();
for(int i = 0; i != 10; ++i) {
ivec.insert(iter,42);
iter= ivec.end();
}
各种方法都可达到目的,也许最后两种方法更好一些。它们使用标准库中定义
的容器操作在容器中增添元素,无需在定义vector对象时指定容器的大小,比
较灵活而且不容易出错。
习题3.17
C++Primer(4版)习题解答
53
重做3.3.2节的习题,用迭代器而不是下标操作来访问vector 中的元素。
【解答】
重做习题3.13如下:
//读一组整数到vector对象,计算并输出每对相邻元素的和
//使用迭代器访问vector中的元素
#include<iostream>
#include<vector>
usingnamespace std;
intmain()
{
vector<int>ivec;
intival;
//读入数据到vector对象
cout<< "Enter numbers(Ctrl+Z to end):" << endl;
while(cin>>ival)
ivec.push_back(ival);
//计算相邻元素的和并输出
if(ivec.size() == 0) {
cout<< "No element?!" << endl;
return-1;
}
cout<< "Sum of each pair of adjacent elements in the vector:"
<<endl;
vector<int>::size_typecnt = 0;
C++Primer(4版)习题解答
54
for(vector<int>::iterator iter = ivec.begin();
iter< ivec.end()-1;
iter= iter + 2) {
cout<< *iter + *(iter+1) << "\t";
++cnt;
if( cnt % 6 == 0) //每行输出6个和
cout<< endl;
}
if(ivec.size() % 2 != 0) //提示最后一个元素没有求和
cout<< endl
<<"The last element is not been summed "
<<"and its value is "
<<*(ivec.end()-1) << endl;
return0;
}
//读一组整数到vector对象,计算首尾配对元素的和并输出
//使用迭代器访问vector中的元素
#include<iostream>
#include<vector>
usingnamespace std;
intmain()
{
vector<int>ivec;
intival;
C++Primer(4版)习题解答
55
//读入数据到vector对象
cout<< "Enter numbers(Ctrl+Z to end):" << endl;
while(cin>>ival)
ivec.push_back(ival);
//计算首尾配对元素的和并输出
if(ivec.size() == 0) {
cout<< "No element?!" << endl;
return-1;
}
cout<< "Sum of each pair of counterpart elements in the vector:"
<<endl;
vector<int>::size_typecnt=0;
for(vector<int>::iterator first = ivec.begin(),
last= ivec.end() - 1;
first< last;
++first,--last) {
cout<< *first + *last << "\t";
++cnt;
if( cnt % 6 == 0) //每行输出6个和
cout<< endl;
}
if(first == last) //提示居中元素没有求和
cout<< endl
<<"The center element is not been summed "
C++Primer(4版)习题解答
56
<<"and its value is "
<<*first << endl;
return0;
}
重做习题3.14如下:
//读入一段文本到vector对象,每个单词存储为vector 中的一个元素。
//把vector对象中每个单词转化为大写字母。
//输出vector对象中转化后的元素,每8个单词为一行输出。
//使用迭代器访问vector中的元素
#include<iostream>
#include<string>
#include<vector>
#include<cctype>
usingnamespace std;
intmain()
{
vector<string>svec;
stringstr;
//读入文本到vector对象
cout<< "Enter text(Ctrl+Z to end):" << endl;
while(cin>>str)
svec.push_back(str);
//将vector对象中每个单词转化为大写字母,并输出
if(svec.size() == 0) {
C++Primer(4版)习题解答
57
cout<< "No string?!" << endl;
return-1;
}
cout<< "Transformed elements from the vector:"
<<endl;
vector<string>::size_typecnt = 0;
for(vector<string>::iterator iter = svec.begin();
iter!= svec.end(); ++iter) {
for(string::size_type index = 0; index != (*iter).size();
++index)
if(islower((*iter)[index]))
//单词中下标为index的字符为小写字母
(*iter)[index]= toupper((*iter)[index]);
cout<< *iter << " ";
++cnt;
if(cnt % 8 == 0)//每8个单词为一行输出
cout<< endl;
}
return0;
}
习题3.18
编写程序来创建有10个元素的vector 对象。用迭代器把每个元素值改为当前
值的2倍。
【解答】
C++Primer(4版)习题解答
58
//创建有10个元素的vector 对象,
//然后使用迭代器将每个元素值改为当前值的2倍
#include<iostream>
#include<vector>
usingnamespace std;
intmain()
{
vector<int>ivec(10, 20);//每个元素的值均为20
//将每个元素值改为当前值的2倍
for(vector<int>::iterator iter = ivec.begin();
iter!= ivec.end(); ++iter)
*iter= (*iter)*2;
return0;
}
习题3.19
验证习题3.18的程序,输出vector 的所有元素。
【解答】
//创建有10个元素的vector 对象,
//然后使用迭代器将每个元素值改为当前值的2倍并输出
#include<iostream>
#include<vector>
usingnamespace std;
intmain()
{
C++Primer(4版)习题解答
59
vector<int>ivec(10, 20);//每个元素的值均为20
//将每个元素值改为当前值的2倍并输出
for(vector<int>::iterator iter = ivec.begin();
iter!= ivec.end(); ++iter) {
*iter= (*iter)*2;
cout<< *iter << " ";
}
return0;
}
习题3.20
解释一下在上几个习题的程序实现中你用了哪种迭代器,并说明原因。
【解答】
上述几个习题的程序实现中使用了类型分别为vector<int>::iterator和
vector<string>::iterator的迭代器,通过这些迭代器分别访问元素类型为
int和string的vector 对象中的元素。
习题3.21
何时使用const迭代器?又在何时使用const_iterator?解释两者的区别。
【解答】
const迭代器是迭代器常量,该迭代器本身的值不能修改,即该迭代器在定义时
需要初始化,而且初始化之后,不能再指向其他元素。若需要指向固定元素的
迭代器,则可以使用const迭代器。
const_iterator是一种迭代器类型,对这种类型的迭代器解引用会得到一个指
向const对象的引用,即通过这种迭代器访问到的对象是常量。该对象不能修
改,因此,const_iterator类型只能用于读取容器内的元素,不能修改元素的
值。若只需遍历容器中的元素而无需修改它们,则可以使用const_iterator。
习题3.22
如果采用下面的方法来计算mid会产生什么结果?
C++Primer(4版)习题解答
60
vector<int>::iteratormid = (vi.begin() + vi.end())/2;
【解答】
将两个迭代器相加的操作是未定义的,因此用这种方法计算mid会出现编译错
误。
习题3.23
解释下面每个bitset对象包含的位模式:
(a)bitset<64> bitvec(32);
(b)bitset<32> bv(1010101);
(c)string bstr; cin >> bstr; bitset<8> bv(bstr);
【解答】
(a)bitvec有64个二进制位,(位编号从0 开始)第5位置为1,其余位置均
为0。
(b)bv有32个二进制位,(位编号从0 开始)第0、2、4、5、7、8、11、13、
14、16、17、18、19位置为1,其余位置均为0。因为十进制数1010101对应的
二进制数为000000000000011110110100110110101。
(c)bv有8个二进制位,(位编号从0 开始)用读入的字符串的从右至左的8
个字符对bv的0~7 位进行初始化。
习题3.24
考虑这样的序列1,2,3,5,8,13,21,并初始化一个将该序列数字所对应的位置设
置为1的bitset<32>对象。然后换个方法,给定一个空的bitset对象,编写一
小段程序把相应的数位设置为1。
【解答】
bitset<32>对象的初始化:
bitset<32>bv(0x20212e)
方法二:
bitset<32>bv;
intx = 0, y = 1, z;
C++Primer(4版)习题解答
61
z= x + y;
while(z <= 21) {
bv.set(z);
x= y;
y= z;
z= x + y;
}
注意,设置为1的数位的位编号符合斐波那契数列的规律。
- C++ Primer 【第四版】第三章 标准库类型
- 【重学《C++Primer第四版》】第三章、标准库类型
- 《C++Primer》 第三章 标准库类型
- C++primer第三章:标准库类型
- C++primer第4版第三章标准库类型
- (读后感)C++ Primer(第四版) 第三章 快速入门 标准库类型
- C++Primer笔记 第三章 标准库类型
- C++Primer 学习笔记 第三章(标准库类型)
- C++primer学习笔记-第三章标准库类型
- 《C++ Primer》 第四版 第3章 标准库类型
- C++ primer 第三章 标准库类型
- C++ Primer 第三章 标准库类型
- C++ Primer 第三章 标准库类型
- 《c++ primer》第三章--标准库类型
- C++ primer 第三章 标准库类型
- C++ Primer 第三章 标准库类型
- C++primer(第五版)第三章中标准库类型Vector、迭代器和数组
- C++ Primer(第四版)笔记1 标准库string类型
- ID3算法 改进的C4.5算法 决策树算法
- 方格取数
- iOS7—图像资源Images Assets
- Html中的过滤器的相关操作
- 全景探秘游戏设计艺术 笔记
- C++ Primer 【第四版】第三章 标准库类型
- 矩阵LU分解分块算法实现
- 无锁队列
- java泛型
- Android usb 无访问权限
- 可用谷歌ip地址
- 8月,推荐给程序员们的技术书
- 成为优秀程序员的十个有效方法
- makefile编写