本门答案,部分参考于C++ Primer 习题集
文章目录
第一章答案
第二章答案
3.1
1.9 改写
#include<iostream>
using std::cout;
using std::endl;
int main(void) {
int sum = 0, i = 50;
while (i <= 100) {
sum = sum + i;
++i;
}
cout << sum << endl;
return 0;
}
1.10 改写
#include<iostream>
using std::cout;
using std::endl;
int main(void) {
int sum = 0, i = 10;
while (i >= 0) {
cout << i <<endl;
--i;
}
return 0;
}
1.11改写
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
int main(void) {
int a, b, c;
cin >> a >> b;
if (a < b) {
c = a;
a = b;
b = c;
}
while (b <= a) {
cout << b << endl;
++b;
}
return 0;
}
2.41改写
3.2
一次输入一行
#include<iostream>
#include<string>
using std::cout;
using std::endl;
using std::cin;
using std::string;
int main(void) {
string line;
while (getline(cin, line)) {
cout << line;
}
return 0;
}
一次输入一个词
#include<iostream>
#include<string>
using std::cout;
using std::endl;
using std::cin;
using std::string;
int main(void) {
string line;
while (cin>>line) {
cout << line;
}
return 0;
}
3.3
这题参考答案写的比较好,借鉴了
标准库string的输入运算符自动忽略字符串开头的空白(包括空格符,换行符,制表符)从第一个真正的字
符开始读起,直到遇到下一处空白为止.
如果希望在最终的字符串中保留输入的空白符,应该使用getline函数代替原来的>>运算符,getline从给
定的输入流中读取数据,直到遇到换行符为止.此时,换行符也读取进来,但是并不存储在最后的字符串
中
下面是一个例子.
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string word, line;
cout << "请选择读取字符串的方式:1 表示逐词读取,2 表示整行读取" << endl;
char ch;
cin >> ch;
if (ch == '1') {
cout << "请输入字符串: Welcome to C++ family! " << endl;
cin >> word;
cout << "系统读取的有效字符串:" << endl;
cout << word << endl;
return 0;
}
//清空输入缓冲区
cin.clear();
cin.sync();
if (ch == '2') {
cout << "请输入字符串: Welcome to C++ family! " << endl;
getline(cin, line);
cout << "系统读取的有效字符串:" << endl;
cout << line << endl;
return 0;
}
cout << "您的输入有误" << endl;
return -1;
}
3.4
根据大小来输出
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string arr1 = "", arr2 = "";
cin >> arr1 >> arr2;
if (arr1 > arr2) {
cout << arr1;
}
else if (arr1 < arr2) {
cout << arr2;
}
}
根据长度来输出
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string arr1 = "", arr2 = "";
cin >> arr1 >> arr2;
if (arr1.length() > arr2.length()) {
cout << arr1;
}
else if (arr1.length() < arr2.length()) {
cout << arr2;
}
}
3.5
没有空格的程序
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string sum="", part="";
while (cin >> part) {
sum += part;
}
cout << sum;
}
有空格的程序
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string sum="", part="";
while (cin >> part) {
part += " ";
sum += part;
}
cout << sum;
}
3.6
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string sum("I will find a job");
for (auto &a : sum) {
a = 'X';
}
cout << sum;
}
3.7
我估计可能会出警告信息,但是编译器也可以完成任务
代码如下:
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string sum("I will find a job");
for (char &a : sum) {
a = 'X';
}
cout << sum;
}
最后结果就是没有警告,也没有什么错误信息,也可以完成任务.
书中有解释到,我们用auto自动推断的话,也是char类型的
3.8
传统的for循环
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string sum("I will find a job");
for (int i = 0; i < sum.length(); i++) {
sum[i] = 'X';
}
cout << sum;
}
传统的while循环
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string sum("I will find a job");
int i = 0;
while (i < sum.length()) {
sum[i] = 'X';
i++;
}
cout << sum;
}
3.9
不合法,这个语句的作用就是输出字符串s的第一个元素
不合法的原因就是,s是空的,没有任何的元素
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string s;
cout << s[0] << endl;
}
但是在我的VS2019中,不会出错,但是,在实际写的过程中,绝对不要这样写.
3.10
这个是不带空格的.带空格的只要把cin哪里,改为geline就可以了.
#include<iostream>
#include<string>
using namespace std;
int main(void) {
string s="";
string s_copy="";
//cin >> s;
getline(cin, s);
for (auto c : s) {
if (!ispunct(c)) {
s_copy.push_back(c);
}
}
s = s_copy;
cout << s;
}
3.11
合法,是常量引用
s是一个常量字符串,auto自动退出来就是一个常量字符引用.
下面是一个例子
#include<iostream>
#include<string>
using namespace std;
int main(void) {
const string s = "Keep out!";
for (auto& c = s) {
c = 'X';
}
return 0;
}
错误信息如下:
3.12
(a)
是正确的,它的类型是
vector<vector<int>>
(b)
是错误的,两个的类型都不一样
vector<string> //第一个的类型
vector<vector<int>> //第二个的类型1
©
vector<string> //类型
是正确的,创建了10个值为 null 的字符串
3.13
(a)
0个元素,因为没有值.
(b)
10个元素,默认初始化
©
10个元素,值都是42
(d)
一个元素,10
(e)
二个元素,一个10,一个42
(f)
10个元素,都是默认初始化
(g)
10个元素,值都是 hi
3.14
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(void) {
vector<int> s;
int t=0;
while (cin >> t) {
s.push_back(t);
}
for (auto p : s) {
cout << p << endl;
}
return 0;
}
3.15
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(void) {
vector<string> s;
string t="";
while (cin >> t) {
s.push_back(t);
}
for (auto p : s) {
cout << p << endl;
}
return 0;
}
3.16
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(void){
vector<int> v1;
vector<int> v2(10);
vector<int> v3(10,42);
vector<int> v4{10};
vector<int> v5{10,42};
vector<string> v6{10};
vector<string> v7{10,"hi"};
cout<<"v1的容量为:";
cout<<v1.size()<<endl;
for(auto p:v1){
cout<<p<<" ";
}
cout<<"\n";
cout<<"v2的容量为:";
cout<<v2.size()<<endl;
for(auto p:v2){
cout<<p<<" ";
}
cout<<"\n";
cout<<"v3的容量为:";
cout<<v3.size()<<endl;
for(auto p:v3){
cout<<p<<" ";
}
cout<<"\n";
cout<<"v4的容量为:";
cout<<v4.size()<<endl;
for(auto p:v4){
cout<<p<<" ";
}
cout<<"\n";
cout<<"v5的容量为:";
cout<<v5.size()<<endl;
for(auto p:v5){
cout<<p<<" ";
}
cout<<"\n";
cout<<"v6的容量为:";
cout<<v6.size()<<endl;
for(auto p:v6){
cout<<p<<" ";
}
cout<<"\n";
cout<<"v7的容量为:";
cout<<v7.size()<<endl;
for(auto p:v7){
cout<<p<<" ";
}
cout<<"\n";
return 0;
}
结果如下:
v1的容量为:0
v2的容量为:10
0 0 0 0 0 0 0 0 0 0
v3的容量为:10
42 42 42 42 42 42 42 42 42 42
v4的容量为:1
10
v5的容量为:2
10 42
v6的容量为:10
v7的容量为:10
hi hi hi hi hi hi hi hi hi hi
···
和3.13的结果一样.
3.17
我的答案
-理解的是这样的
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<string> s;
string p;
while(cin>>p){
s.push_back(p);
}
for(int i=0;i<s.size();i++){
s[i][0]=toupper(s[i][0]);
}
for(auto i:s){
cout<<i<<endl;
}
return 0;
}
书上的代码
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<string> s;
string p;
while(cin>>p){
s.push_back(p);
}
for(auto &i:s){
for(auto &j :i){
j = toupper(j);
}
}
for(auto i:s){
cout<<i<<endl;
}
return 0;
}
3.18
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<int> ivec;
ivec.push_back(42);
cout<<ivec[0]<<endl;
return 0;
}
3.19
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<int> a1(10,42);
vector<int> a2 = {42,42,42,42,42,42,42,42,42,42};
vector<int> a3{42,42,42,42,42,42,42,42,42,42};
vector<int> a4;
vector<int> a5(10);
for(auto &i:a5){
i = 42;
}
for(int i = 0;i < 10;i++){
a4.push_back(42);
}
//测试中文乱码
cout<<"中文乱码爷是真的烦"<<endl;
cout<<a1.size()<<endl;
cout<<a2.size()<<endl;
cout<<a3.size()<<endl;
cout<<a4.size()<<endl;
cout<<a5.size()<<endl;
for(auto a:a1){
cout<<a<<" ";
}
cout<<"\n";
for(auto a:a2){
cout<<a<<" ";
}
cout<<"\n";
for(auto a:a3){
cout<<a<<" ";
}
cout<<"\n";
for(auto a:a4){
cout<<a<<" ";
}
cout<<"\n";
for(auto a:a5){
cout<<a<<" ";
}
cout<<"\n";
return 0;
}
这题中最好的初始化是a1,总结一下
① 当初始化的对象是一系列重复的值的时候,a1最好
② 当初始化的对象是没有规律的时候,a4的方法较好.
3.20
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<int> arr;
int a;
while(cin>>a){
arr.push_back(a);
}
for(int i=0;i<arr.size()-1;i+=2){
cout<<arr[i]+arr[i+1]<<endl;;
}
return 0;
}
改写后
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<int> arr;
int a;
while(cin>>a){
arr.push_back(a);
}
int right=(int)arr.size()-1;
for(int i=0;i<right/2;++i){
cout<<arr[i]+arr[right-i]<<endl;
}
return 0;
}
3.21
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(void){
vector<int> v1;
vector<int> v2(10);
vector<int> v3(10,42);
vector<int> v4{10};
vector<int> v5{10,42};
vector<string> v6{10};
vector<string> v7{10,"hi"};
cout<<"v1的容量为:";
cout<<v1.size()<<endl;
for(auto p = v1.cbegin();p!=v1.cend();p++){
cout<<*p ;
}
cout<<"\n";
cout<<"v2的容量为:";
cout<<v2.size()<<endl;
for(auto p = v2.cbegin();p!=v2.cend();p++){
cout<<*p ;
}
cout<<"\n";
cout<<"v3的容量为:";
cout<<v3.size()<<endl;
for(auto p = v3.cbegin();p!=v3.cend();p++){
cout<<*p ;
}
cout<<"\n";
cout<<"v4的容量为:";
cout<<v4.size()<<endl;
for(auto p = v4.cbegin();p!=v4.cend();p++){
cout<<*p ;
}
cout<<"\n";
cout<<"v5的容量为:";
cout<<v5.size()<<endl;
for(auto p = v5.cbegin();p!=v5.cend();p++){
cout<<*p ;
}
cout<<"\n";
cout<<"v6的容量为:";
cout<<v6.size()<<endl;
for(auto p = v6.cbegin();p!=v6.cend();p++){
cout<<*p ;
}
cout<<"\n";
cout<<"v7的容量为:";
cout<<v7.size()<<endl;
for(auto p = v7.cbegin();p!=v7.cend();p++){
cout<<*p ;
}
cout<<"\n";
return 0;
}
3.22
这题的答案,参考与书上.
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(void){
vector<string> text;
string s;
while(getline(cin,s))
text.push_back(s);
for(auto it = text.begin();it != text.end()&& !it->empty();++it){
for(auto it2 = it->begin();it2!=it->end();++it2)
*it2 = toupper(*it2);
cout<<*it<<endl;
}
return 0;
}
3.23
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(void){
vector<int> a(10);
int i=0;
for(int i=0;i < 10;i++){
cin>>a[i];
}
for(auto it = a.begin();it != a.end();++it){
*it = (*it)*2;
}
for(auto it = a.begin();it != a.end();++it){
cout<<*it<<endl;
}
return 0;
}
3.24
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<int> arr;
int a;
while(cin>>a){
arr.push_back(a);
}
for(auto it = arr.cbegin();it!=arr.cend();++it){
cout<<(*it)+(*(++it))<<endl;
}
return 0;
}
改写后
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<int> arr;
int a;
while(cin>>a){
arr.push_back(a);
}
for(auto cb = arr.cbegin(),ce = arr.cend()-1;cb<=ce;++cb,--ce){
cout<<(*cb)+(*ce)<<endl;
}
return 0;
}
3.25
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<unsigned> scores(11,0);
unsigned p=1;
auto it = scores.begin();
while(cin>>p){
if(p<=100){
++(*(it+p/10));
}
}
for(auto i:scores)
cout<<i<<endl;
return 0;
}
3.26
这题答案讲的比较完整,贴一下
C++并没有定义两个迭代器的加分运算,实际上,直接把两个迭代器加起来是没有意义的
与之相反,C++定义了迭代器的减法运算,两个迭代器相减的结果是它们之间的距离,也就是说,将运算符右侧的迭代器向前移动多少个元素后可以得到左侧的迭代器,参与运算的迭代器必须指向同一个容器中的元素或尾后元素.
另外,C++还定义了迭代器与整数的加减法运算,用以控制迭代器在容器中左右移动.
在本题中,因为迭代器的加法不存在,所以mid=(beg+end)/2是不合法的.
3.27
(a)
非法的,数组的维度必须是常量
(b)
合法的,因为4*7-14是一个常量表达式
©
非法的,这个函数的返回值不是常量.
除非定义为constepr
(d)
非法的,字符数组的最后需要加一个结束符
'\n'
3.28
① string 只要不被初始化,就是空串
② int等类型,跟是否是全局变量有关.
ia里面的都是0
ia2里面的值是未定义的,在不同的编译器上有不同的值
3.29
文字题,参考答案
相同的地方:
① :都能存放相同的对象,而对象本身没有名字,需要通过其所在的位置访问.
不同的地方:
① :数组与vector的最大不同是,数组的大小固定不变,不能随意向数组中增加元素,灵活度不够
3.30
不应该从1开始,不应该取到10
正确的如下:
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
constexpr size_t array_size = 10;
int ia[array_size];
for (size_t ix = 0;ix < array_size ;++ix)
ia[ix] = ix;
return 0;
}
3.31
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
int a[10];
for (size_t ix = 0;ix < 10 ;++ix)
a[ix] = ix;
for (size_t ix = 0;ix < 10 ;++ix)
cout << a[ix]<<" ";
return 0;
}
3.32
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
vector<int>a(10);
for (size_t ix = 0;ix < 10 ;++ix)
a[ix] = ix;
for (size_t ix = 0;ix < 10 ;++ix)
cout << a[ix]<<" ";
return 0;
}
3.33
会产生未定义的值,变量在使用之前,一定要初始化.
3.34
在逻辑上,这个就算不是指向同一个对象都是可以的.
因为
int b[10],*p1=b,*p2=&b[5];
p1 += p2 - p1; //p1 = p1 + p2 - p1;
非法的情况,只有在这两个指针的类型不匹配.
3.35
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
int a[5]={1,2,3,4,5};
int *p=a;
for(;p<(a+5);++p){
*p=0;
}
p=a;
for(;p<(a+5);++p){
cout<<*p;
}
return 0;
}
3.36
①: 先判断长度相等不相等,不相等就肯定不一样
②: 然后判断判断类型,类型是否相等(我这里偷懒就没写)
③: 最后在循环遍历判断.
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
int a[5],b[6];
//vector<int> a(5)
//vector<int> b(6)
if(a.length()!=b.length()){
cout<<"不相等";
}
else {
for(int i=0;i<a.length();++i){
if(a[i]!=b[i]){
cout<<"不相等";
break;
return 0;
}
}
cout<<"相等";
}
return 0;
}
3.37
含义就是通过指针cp把数组ca输出出来—这是我一开始想的
后来发现不是这样的.
ca数组是列表初始化,字符串的结尾没有结束符,所以会cp会多循环几次.
代码如下:
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
const char ca[]={'h','e','l','l','o'};
const char *cp=ca;
while(*cp){
cout<<*cp<<endl;
cp++;
}
return 0;
}
结果如下:
h
e
l
l
o
a
改进后的代码如下:
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
const char ca[]={'h','e','l','l','o','\0'};
const char *cp=ca;
while(*cp){
cout<<*cp<<endl;
cp++;
}
return 0;
}
结果如下:
h
e
l
l
o
3.38
参考书中的答案
指针有三个属性(主要)
① 指针本身的值是一个内存地址值,表示指针所指对在内存中的存储地址,指针所指的对象可以通过解引用指针访问.因为指针也是一个对象,所以指针也存储在内存的某个位置,它有自己的地址.所以有“指针的指针”
② 指针的值是它所指对象的内存地址,如果把两个指针相加,那就是把内存中的两个地址相加,这是无意义的,但是如果两个指针指向的是同一个数组的不同元素,那么它们相减的结果就是表示了这两个元素之间的距离.
PS(数组中的地址是连续的)
3.39
string对象
#include<iostream>
#include<vector>
#include<cctype>
#include<string>
using namespace std;
int main(void){
string a,b;
a = "我要拥有腹肌,学会人情事故,开始赚钱,早睡早起,学会换头术,尽量少的和妈妈吵架,找到工作,学英语.";
b = "如果,想让上面的东西都成真的话,从现在开始,就要努力努力在努力.";
if(a>b)
cout<<"a>b";
else if(a==b)
cout<<"a==b";
else
cout<<"a<b";
return 0;
}
char
#include<iostream>
#include<vector>
#include<cctype>
#include<string.h>
using namespace std;
int main(void) {
//char a[] = "我要拥有腹肌,学会人情事故,开始赚钱,早睡早起,学会换头术,尽量少的和妈妈吵架,找到工作,学英语";
//char b[] = "如果,想让上面的东西都成真的话,从现在开始,就要努力努力在努力.";
char c[] = "abc";
char d[] = "def";
int resu = strcmp(c, d);
if (resu > 0)
cout << "a>b";
else if (resu == 0)
cout << "a==b";
else
cout << "a<b";
return 0;
}
3.40
#include<iostream>
#include<vector>
#include<cctype>
#include<string.h>
using namespace std;
int main(void) {
char a[] = "我要拥有腹肌,学会人情事故,开始赚钱,早睡早起,学会换头术,尽量少的和妈妈吵架,找到工作,学英语";
char b[] = "如果,想让上面的东西都成真的话,从现在开始,就要努力努力在努力.";
char c[300];
// char a[] = "abc";
// char b[] = "efg";
strcpy(c,a);
// cout<<c<<endl;
strcat(c,b);
cout<<c;
return 0;
}
3.41
#include<iostream>
#include<vector>
#include<cctype>
#include<string.h>
using namespace std;
int main(void) {
int a[5]={1,2,3,4,5};
vector<int> b(begin(a),end(a));
for(auto i:b){
cout<<i<<" ";
}
return 0;
}
3.42
#include<iostream>
#include<vector>
#include<cctype>
#include<string.h>
using namespace std;
int main(void) {
int a[5]={0,0,0,0,0};
vector<int> b{1,2,3,4,5};
for(int i=0;i<5;i++){
a[i] = b[i];
}
for(int i=0;i<5;i++){
cout<<a[i]<<" ";
}
return 0;
}
3.43
#include<iostream>
#include<vector>
#include<cctype>
#include<string.h>
using namespace std;
int main(void) {
int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
cout<<"利用范围for语句输出多维数组的内容:"<<endl;
for(int (&row)[4]:ia){
for(int &col:row)
cout<<col<<" ";
cout<<endl;
}
cout<<"利用普通for语句和下标运算符输出多维数组的内容:"<<endl;
for(int i=0;i!=3;++i){
for(int j=0;j!=4;++j){
cout<<ia[i][j]<<" ";
}
cout<<endl;
}
cout<<"利用普通for语句和指针输出多维数组的内容:"<<endl;
for(int (*p)[4]=ia;p!=ia+3;++p){
for(int *q=*p;q!=*p+4;++q){
cout<<*q<<" ";
}
cout<<endl;
}
return 0;
}
3.44
#include<iostream>
#include<vector>
#include<cctype>
#include<string.h>
using namespace std;
using int_array = int[4];
int main(void) {
int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
cout<<"利用范围for语句输出多维数组的内容:"<<endl;
for(int_array &row:ia){
for(int &col:row)
cout<<col<<" ";
cout<<endl;
}
cout<<"利用普通for语句和下标运算符输出多维数组的内容:"<<endl;
for(int i=0;i!=3;++i){
for(int j=0;j!=4;++j){
cout<<ia[i][j]<<" ";
}
cout<<endl;
}
cout<<"利用普通for语句和指针输出多维数组的内容:"<<endl;
for(int_array *p=ia;p!=ia+3;++p){
for(int *q=*p;q!=*p+4;++q){
cout<<*q<<" ";
}
cout<<endl;
}
return 0;
}
3.45
#include<iostream>
#include<vector>
#include<cctype>
#include<string.h>
using namespace std;
int main(void) {
int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
cout<<"利用范围for语句输出多维数组的内容:"<<endl;
for(auto &row:ia){
for(auto &col:row)
cout<<col<<" ";
cout<<endl;
}
cout<<"利用普通for语句和下标运算符输出多维数组的内容:"<<endl;
for(auto i=0;i!=3;++i){
for(auto j=0;j!=4;++j){
cout<<ia[i][j]<<" ";
}
cout<<endl;
}
cout<<"利用普通for语句和指针输出多维数组的内容:"<<endl;
for(auto *p=ia;p!=ia+3;++p){
for(auto *q=*p;q!=*p+4;++q){
cout<<*q<<" ";
}
cout<<endl;
}
return 0;
}