本門答案,部分參考於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;
}