c++ primer v5 solutions

c++ primer version 5 题解

Chapter 1

1.3

1
2
3
4
#include<iostream>
int main(){
std::cout<<"Hello, World.";
}

1.6

程序不合法。; 则意味着该语句的结束。第二行的语句则与第一行无关,因此需要重新声明 std::cout<<

1.8

  1. 合法
  2. 合法
  3. 非法
  4. 合法

1.9

1
2
3
4
5
6
7
8
9
#include<iostream>
int main()
{
int i = 50,sum = 0;
while(i <= 100){
sum += i;
i++;
}
}

1.10

1
2
3
4
5
6
7
8
9
#include<iostream>
int main()
{
int i = 10;
while (i >= 0){
std::cout<<" "<<i;
i--;
}
}

1.11

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
int main()
{
int i,j,low;
std::cout<<"Please input two int numbers:";
std::cin>>i>>j;
low = i > j? j:i;
high = i > j? i:j;
while(low <= high){
std::cout<<low<<" ";
low++;
}
}

1.12

程序是将 -100 到 100 的所有整数相加,sum 终值为 0。

1.16

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
int main()
{
int sum = 0, value = 0;
while (std::cin>>value)
{
sum += value;
}
std::cout<<sum;
return 0;
}

Chapter 2

2.1

  • An int, long, long long and short types are representation of integral types of a chunk of allocated memory. The difference between them is in the size of the representation (in bytes) of the respective type, which is often implementation dependent.

  • The unsigned type represents a positive value, while an unsigned represents both positive an negative values of an integral type (except for bool). The limits range of the value depends on the size of integral type. Given that unsigned holds only positive value, it has a higher max limit.

  • A float and a double are floating-point types that represent "single-, double-, and extended-precision values." Their representation is implementation dependent. Most compilers follow the IEEE 754 standard at least for float and double.

2.2

使用 float, double 类型。

2.5

2.6

1
2
3
4
5
#include<iostream>
int main()
{
std::cout<<2<<'\115'<<'\n';
}

2.12

  1. 非法;(b) 非法;(c) 非法;(d) 非法;(e) 合法

2.13

1
2
3
4
5
6
7
int i = 42;
int main()
{
int i = 100;
int j = i;
}
// j 为 100

2.14

1
2
3
4
5
6
int i = 100, sum = 0;
for(int i = 0; i != 10; i++){
sum += i;
}
std::cout<< i <<" "<< sum <<endl;
// 将会输出 100 45

2.15

  1. 合法;(b) 非法;(c) 合法;(d) 非法

2.16

  1. 合法;(b) 合法;(c) 合法;(d) 合法

2.17

1
2
3
4
int i, &ri = i;
i = 5; ri = 10;
std::cout<<i<<" "<<ri<<std::endl;
// 输出 10 10

2.19

reference:

  • the use of & before an type declares a reference. E.g.: int &i = i;
  • not an object in memory
  • must be initialized
  • its binding cannot be changed after initial definition

pointer:

  • declared with * symbol. E.g.: int *p;
  • assigned an address with an assign operator. E.g.: p = &a;
  • assigned the value to which a pointer points to is dereferenced with . E.g.: b = p
  • is an object in memory
  • can be declared but not initialized
  • holds an address as a value
  • its value can be change to point to another address
  • can be used in pointer asthmatics

2.20

1
2
3
4
int i = 42;
int *pi = &i;
*pi = *pi * *pi;
// 等价于 i = i * i

2.24

p is a pointer to void pointing to an int, while lp is a pointer to a long pointing to an int. p is legal and lp is not because a pointer must match the type of object it is pointing to, unless it is a void pointer.

2.26

  1. 非法;(b) 合法;(c) 合法;(d) 合法;非法

Chapter 3

3.2

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
#include<string>
using namespace std;
int main()
{
string word;
while(getline(cin, word)){
cout<<word<<endl;
}
return 0;
}

3.3

  • string 类将空白字符视为字符串的结束标志。
  • getline 函数将回车键视为读入的结束标志。

3.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1, s2;
cin>>s1>>s2;
if(s1 == s2)
cout<<"相等";
else if(s1 > s2)
cout<<s1;
else
cout<<s2;
return 0;
}

3.5

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1, output;
while(cin>>s1){
output += s1;
}
cout<<output;
return 0;
}

3.6

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1="TLDX";
for(auto &c : s1)
c = 'X';
cout<<s1;
return 0;
}

3.10

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1="TLDX!TLDX!TLDX!";
for(auto c : s1){
if(!ispunct(c))
cout<<c;
}
return 0;
}

3.11

合法。c 的类型为 const char &

3.12

  1. 正确;(b) 错误;(c) 正确

3.13

  1. 0;(b) 10;(c) 10;(d) 1;(e) 2;(f) 10;(g) 10

3.14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> s;
int a;
while(cin >> a){
s.push_back(a);
}
for(auto c : s){
cout<<c<<" ";
}
cout<<"\n";
return 0;
}

3.15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<string> s;
string a;
while(cin >> a){
s.push_back(a);
}
for(auto c : s){
cout<<c<<" ";
}
cout<<"\n";
return 0;
}

3.17

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<string> s1;
string s2;
while(cin >> s2 ){
for(auto &i : s2){
i = toupper(i);
}
s1.push_back(s2);
cout<<s2<<'\n';
}
}

3.18

1
2
3
//不合法,修改为:
vector<int> ivec;
ivec.push_back(42);

3.19

1
2
3
4
//我更推荐第一种
vector<int> s1 = (10, 42); //第一种
vector<int> s1 = {42,42,42,42,42,42,42,42,42,42}; //第二种
vecrot<int> s1; for(int i = 0; i < 10; i++) s1.push_back(42); //第三种

3.20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
int a;
vector<int> ivec;
while( cin>>a )
ivec.push_back(a);
int size = ivec.size();
for(int i = 0; i < size-1; i++)
cout<<ivec[i] + ivec[i+1]<<" ";
cout<<'\n';
for(int i = 0; i < size/2; i++)
cout<<ivec[i] + ivec[size-i-1]<<" ";
cout<<'\n';
return 0;
}

3.22

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<string> s1;
string line;
while( getline(cin, line)){
s1.push_back(line);
}
for(auto it = s1.cbegin(); it != s1.cend() && !it->empty(); it++){
for(auto &c : *it){
c = toupper(c);
}
cout<<*it<<"\n";
}
return 0;
}

3.23

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> ivec;
int c;
for(int i = 0; i < 10; i++){
cin>>c;
ivec.push_back(c);
}
for(auto it = ivec.begin(); it != ivec.end(); it++){
*it = *it * 2;
}
for(auto it = ivec.begin(); it != ivec.end(); it++)
cout<<*it<<" ";
return 0;
}

3.25

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
vector<int> scores(11,0);
int grade;
auto it = scores.begin();
while( cin>>grade){
if(grade <= 100){
++*(it + grade/10);
}
}
for(auto &i : scores)
cout<<i<<" ";
return 0;
}

3.26

因为两个迭代器相加得到的并非迭代器,是非法结果。

3.31

1
2
3
4
5
6
7
8
#include<iostream>
int main()
{
int a[10] = {0};
for(int i = 0; i < 10; i++){
a[i] = i;
}
}

3.33

如果 scores是全局变量,则会自动初始化为 0。如果是局部变量,则 scores 中内容是未定数,之后的语句 ++scores[grade/10] 会发生未知错误。

3.34

程序作用是将 p1 向前移动 p2-p1 个位置;当 p1 + (p2 - p1) 超过数组索引时,为非法访问。

3.35

1
2
3
4
5
6
7
8
9
10
#include<iostream>
using namespace std;
int main()
{
int a[]={1,2,3,4,5};
for(int *p = a; p <a + 5; ++p)
*p = 0;
for(auto c: a)
cout<<c<<" ";
}

3.36

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
using namespace std;
int main()
{
int a[] = {10,20,30,40,50};
int b[] = {10,20,30,40,50};
auto abeg = begin(a); auto aend = end(a);
auto bbeg = begin(b); auto bend = end(b);
while(abeg < aend){
if(*abeg != *bbeg)
break;
++abeg;
++bbeg;
}
if(abeg == aend && bbeg == bend)
cout<<"相等";
else
cout<<"不相等";
return 0;
}
//使用 vector 更简单,直接判断即可。

3.38

指针内容表示的是地址,两个指针相加表示两个地址相加,可能会得到非法地址。

3.41

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a[]={1,2,3,4,5};
vector<int> ivec(begin(a), end(a));
for(auto c : a)
cout<<c<<" ";
return 0;
}

3.43

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
int row = 3, col = 4;
int ai[row][col]={
{0,1,2,3},
{4,5,6,7},
{8,9,10,11}
};
//第一种
for(int (&arr)[col] : ai){
for(int &c : arr)
cout<<c<<" ";
}
cout<<'\n';
//第二种
for(int i = 0; i < row; ++i){
for(int j = 0; j < col; ++j){
cout<<ai[i][j]<<" ";
}
}
//第三种
cout<<'\n';
for(int (*p)[col] = ai; p != ai + row; ++p){
for(int *q = *p; q != *p + col; ++q){
cout<<*q<<" ";
}
}
}

Chapter 4

4.10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> ivec;
int c;
while( cin>>c ){
if(c == 42)
break;
ivec.push_back(c);
}
for(auto c : ivec)
cout<<c<<" ";
return 0;
}

4.17

说说前置递增运算符和后置递增运算符的区别。

前置递增运算符是先递增,再将递增后的值赋值给其他变量,后置递增运算符是递增后,将对象原始值的副本返回

4.21

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> ivec;
int c;
while( cin>>c ){
if ( c%2 != 0 )
c = c*2;
ivec.push_back(c);
}
for (auto c : ivec)
cout<< c <<" ";
return 0;
}

4.28

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
using namespace std;
int main()
{
cout<<"char: "<<sizeof(char)<<'\n';
cout<<"int: "<<sizeof(int)<<'\n';
cout<<"float: "<<sizeof(float)<<'\n';
cout<<"double: "<<sizeof(double)<<'\n';
cout<<"long: " <<sizeof(long)<<'\n';
cout<<"long long: "<<sizeof(long long);
}

Chapter 5

5.5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
using namespace std;
int main()
{
int grade;
while( cin>>grade ){
if ( grade > 100 )
continue;
if( grade < 60 )
cout<<'F'<<'\n';
else if( grade < 70 )
cout<<'D'<<'\n';
else if( grade < 80 )
cout<<'C'<<'\n';
else if( grade < 90 )
cout<<'B'<<'\n';
else if( grade < 100 )
cout<<'A'<<'\n';
else
cout<<"A++"<<'\n';
}
return 0;
}

5.9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
using namespace std;
int main()
{
int vowel = 0;
char c;
while( cin>>c ){
if((c == 'a') | (c == 'A') | (c == 'E')
| (c == 'e') | (c == 'I') | (c == 'i')
| (c == 'O') | (c == 'o') | (c == 'U')
| (c == 'u'))
++vowel;
}
cout<<vowel;
return 0;
}

5.14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
主要思路是:max 记录当前出现的最大连续次数;
count 记录此次出现的最大连续次数;
利用 s1, s2 来判断前后两个字串是否相等。
每次使用 count 和 max 比较后,都需要将 count 置 1
*/
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1, s2, str;
int max = 0, count = 1;
cin >> s1;
while( cin >> s2 ){
if( s2 == s1){
++count;
}
else if(count > max){
str = s1;
max = count;
count = 1;
}
s1 = s2;
}
if(max > 1)
cout<<str<<":"<<max;
else
cout<<"没有重复的单词出现";
}

5.17

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> iver1{0,1,1,2};
vector<int> iver2{0,1,1,5,3,5,8};
int len = iver1.size() < iver2.size() ? iver1.size() : iver2.size();
for (auto i = 0; i < len; ++i){
if(iver1[i] != iver2[i]){
cout<<"假";
return 0;
}
}
cout<<"真";
return 0;
}

5.19

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1, s2;
cout<<"Please input two strings: ";
cin>>s1>>s2;
if(s1.size() < s2.size())
cout<<s1;
else
cout<<s2;
}

5.20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1,s2;
bool flag = false;
cin>>s1;
while( cin>>s2 ){
if( s1 == s2){
flag = true;
break;
}
else
s1 = s2;
}
if(flag)
cout<<s1;
else
cout<<"No words repeat.";
}

5.23-25

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<iostream>
using namespace std;
int main()
{
int i,j;
while(cin>>i>>j){
try
{
if(j == 0)
throw runtime_error("除数不能为零");
else
cout<<i/j;
}
catch(runtime_error err)
{
cout<<err.what()<<"\nTry again?(y/n)";
char c;
cin >> c;
if(c == 'n')
break;
}
}
return 0;

}

Chapter 6

6.10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
using namespace std;
void swap(int *a, int *b){
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int a, b;
cin >> a >> b;
cout<<"交换前:"<<a<<" " <<b<<'\n';
swap(&a, &b);
cout<<"交换后:"<<a<<" " <<b;
}

6.17

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<iostream>
#include<string>
using namespace std;

bool is_include_upper(const string &s)
{
for(auto c : s){
if('A' <= c && c <= 'Z')
return true;
}
return false;
}

void to_lower(string &s)
{
for(auto &c : s){
c = tolower(c);
}
}
int main()
{
string s = "XiongLingYu";
cout<<is_include_upper(s)<<endl;
to_lower(s);
cout<<s;

}

6.22

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
using namespace std;

void swap(int *(&a), int *(&b))
{
int *t;
t = a, a = b, b = t;
}
int main()
{
int a = 6, b = 8;
int *x = &a, *y = &b;
cout<<x<<" "<<y<<endl;
swap(x, y);
cout<<x<<" "<<y;
return 0;
}

6.27

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<string>
using namespace std;

int sum( initializer_list<int> il ){
int res = 0;
for (auto i : il){
res += i;
}
return res;
}
int main()
{
int ans = sum({ 1, 2, 3, 6, 8, 16});
cout<<ans;
}

6.33

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<vector>
using namespace std;

void print(vector<int>::iterator begin, vector<int>::iterator end)
{
if(begin == end)
return;
cout<<*begin;
print(begin+1, end);
}
int main()
{
vector<int> ivec{1,2,4,5,7,8};
print(begin(ivec), end(ivec));
}

Reference

  1. fsaadatmand-cpp