2024-03-16    2024-03-16    5418 字  11 分钟
CS

C++ Primer

字典

image-20240401191023240

Part I The Basics

2.1.1

image-20240316154743230

2.1:

C++语言规定一个int至少和一个short一样大,一个long至少和一个int一样大,一个long long至少和一个long一样大。每个的最小尺寸分别为:short,16位;int,16位;long,32位;long long,64位。

除去布尔型和扩展的字符型外,其他整形可以划分为带符号的和无符号的两种。带符号类型可以表示正数、负数或0,无符号类型则仅能表示大于等于0的值。

float最小尺寸为6位有效值,double最小尺寸为10位有效值。

2.2:

都选用double,利率4.5%=0.045,本金和付款金额都是以元为单位,钱的最小金额是分,需要精确到小数点后两位,所以都选用double

2.1.2

image-20240316155953500

2.3:

32、2^32 - 32

32、-32、0、0

2.4:

image-20240325091924553

2.1.3

image-20240316161400831

2.5:

(a)字符型,宽字符型,字符串型,宽字符串

(b)整型,无符号整型,长整型,无符号长整型,八进制整型,十六进制整型

(c)浮点型,单精度浮点型,扩展精度浮点型

(d)整型,无符号整型,浮点型,浮点型

2.6:

答:有区别,区别在于上面那行代码定义的month和day为十进制整型数字,而下面的为八进制数,并且int month = 09这句会报错!!!

2.7:

(a)“Who goes with Fergus?” ,string

(b)31.4,long double

(c)3.14,long double

2.2.1

image-20240316163049852

2.9:

(a)非法,>>运算符后面不能定义

(b)非法,花括号进行列表初始化可能会丢失数据,转换未执行

(c)非法,同一语句的初始化应当分别进行

(d)正确,将3.14强制转换为int型后将i初始化

2.10:

global_str = “”;

global_int = 0;

local_int 和 local_str未初始化

2.2.2

image-20240316163822023

2.11:

(a)定义,因为直接将ix初始化抵消了extern的作用

(b)声明并定义,不过没有初始化

(c)声明,使用了extern关键字

2.2.3

image-20240316164141381

2.12:

(a)非法,关键字

(b)合法

(c)非法,不能包含“-”号

(d)非法,只能以字幕开头

(e)合法

2.2.4

image-20240316164622319

2.13:

j = 100;

2.14:

合法,100 45

2.3.1

image-20240316165353782

2.15:

(a)合法

(b)不合法,引用的初始值必须是对象

(c)合法

(d)不合法,引用必须初始化

2.16:

(a)合法,将3.14159赋给d

(b)合法,将0赋值给了d

(c)合法,将0赋值给了i

(d)合法,将0赋值给了i

2.3.2

image-20240316170854045

2.19:

指针是变量,具有自己的地址空间,可以更改指向的同类型对象,无需在定义时赋初值

引用不是变量,没有自己的地址空间,不可以更改引用的指向,它是变量的一个别名

2.20:

将i * i 赋值给了i

2.3.3

image-20240326194618955

(a)

ip是指向int类型的未初始化指针,i是一个int类型的变量,r是对i的引用

(b)

i是int类型的变量,ip是指向int类型的空指针

(c)

ip是指向int类型的未初始化指针,ip2是int类型的变量

2.3.4

image-20240326195954879

2.26:

(a)不合法,常量必须初始化

(b)合法

(c)合法

(d)不合法,试图修改buf常量的值

2.4.2

image-20240326203103294

2.27:

(a)不合法,0是常量,&r不是常量应用

(b)如果i2是const int则不合法

(c)合法

(d)合法

(e)合法

(f)不合法,引用未初始化

(g)合法

2.28:

(a)不合法,cp未初始化

(b)不合法,p2未初始化

(c)不合法,ic未初始化

(d)不合法,p3未初始化

(e)合法,指针常量的指针可以不初始化

2.29:

2.4.3

image-20240326205711638

2.30:

顶层

p2底层,p3既是顶层又是底层,r2底层

2.31:

合法,v2顶层是const

非法,p2底层是const

合法,p2底层const不影响

非法,p3底层是const,p1没有

合法,底层都是const

2.4.4

image-20240327192645414

2.32:

非法,int null = 0, *p = &null;

2.5.2

image-20240327194429966

2.33:

a = 42、b = 42、c = 42、非法、非法、非法

2.35:

j是整型,k是对整型常量的引用,p是指向整型变量的指针

j2常量int,k2常量int的引用

2.5.3

image-20240327203012914

2.36:

a:int,4

b:int,4

c:int,4

d:int &,4

2.37:

a:int,3

b:int,4

c:int,3

d:int &,3

2.38:

decltype处理顶层const和引用的方式与auto不同,如果decltype使用变量作为它的表达式则返回包括const和引用在内的该变量的类型,decltype的结果类型和表达式形式密切相关。比如:

1
2
3
4
5
6
7
8
int i = 10;
const int &j = i;
/*decltype指定类型和auto不一样*/
decltype(j) a = i;	//a为const int &类型,绑定到i
auto b = j;			//b为int类型,值=i
/*decltype指定类型和auto一样*/
decltype(j + 0) c;
auto d = j + 0;

2.6.1

image-20240327210143603

2.39:

image-20240328202725842

2.40:

1
2
3
4
5
6
7
struct Sales_data
{
	string book_name;
    int ISBN;
    Date publish_date;
    double price;
};

2.6.2

image-20240329193650428

2.6.3

image-20240329194302246

image-20240329194613272

3.1

image-20240329201856741

3.2.2

image-20240331185800127

3.2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <iostream>
#include <string>

using std::string;

int main()
{
    string str;
    // getline(std::cin, str);
    std::cin >> str;
    std::cout << str << std::endl;

    return 0;
}

3.3:

string类的输入运算符在遇到空格的时候就停止输入,读取到单个词,忽略了开头和结尾的空格,而getline函数会将空格读入string对象,遇到换行符停止,并将换行符丢弃

3.4:

 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>
#include <string>

using std::string;

int main()
{
    string str1, str2;
    // getline(std::cin, str);
    std::cin >> str1;
    std::cin >> str2;
    // if (str1 > str2)
    //     std::cout << str1;
    // else
    //     std::cout << str2;

    if (str1.size() != str2.size()){
        if(str1.size() > str2.size())
            std::cout << str1 << std::endl;
        else
            std::cout << str2 << std::endl;
    }

    return 0;
}

3.2.3

image-20240331193337978

3.6:

1
2
3
4
5
6
    string str1("Hello World!!!");
    for (auto &s : str1) {
        s = 'x';
    }

    cout << str1 << std::endl;

3.7:

结果一样

3.8:

1
2
3
4
5
6
7
8
9
    string str1("Hello World!!!");
    string str2("nihao shijie");
    for(string::size_type index = 0; index < str1.size(); index++)
        str1[index] = 'x';
    decltype(str1.size()) i = 0;
    while(str2[i] != '\0') {
        str2[i] = 'x';
        i++;
    }

for更好,更只管,并且声明的变量的作用域在for语句内,不会对其他程序有影响

3.3.1

image-20240331200543897

3.12:

(a)正确,ivec为vector<int>类型的vector类型的对象

(b)错误,svec的类型不为vector<int>

(c)正确,svec为包含10个null字符的vector对象

3.13:

(a)0个元素 (b)10个元素,int默认初始值0

(c)10个元素,42 (d)1个元素,10

(e)两个元素,10,42 (f)10个元素,空串

(g)10个元素,“hi”

3.3.2

image-20240331202013700

3.14:

1
2
3
4
5
6
7
	vector<int> ivec;
    int temp;
    while (cin >> temp)
        ivec.push_back(temp);
    for (decltype(ivec.size()) i = 0; i < ivec.size(); i++) {
        cout << ivec[i] << endl;
    }

3.15:

1
2
3
4
5
6
7
    vector<string> svec;
    string temp;
    while (cin >> temp)
        ivec.push_back(temp);
    for (decltype(svec.size()) i = 0; i < svec.size(); i++) {
        cout << svec[i] << endl;
    }

3.3.3

image-20240401190035804

3.16:

 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <vector>
#include <string>

using std::string;
using std::vector;

//懒得写函数了,,,凑合凑合吧
int main()
{
    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"};

    for (decltype(v1.size()) index = 0; index < v1.size(); index++) {
        std::cout << v1[index] << std::endl;
    }

    for (decltype(v2.size()) index = 0; index < v2.size(); index++) {
        std::cout << v2[index] << std::endl;
    }

    for (decltype(v3.size()) index = 0; index < v3.size(); index++) {
        std::cout << v3[index] << std::endl;
    }

    for (decltype(v4.size()) index = 0; index < v4.size(); index++) {
        std::cout << v4[index] << std::endl;
    }

    for (decltype(v5.size()) index = 0; index < v5.size(); index++) {
        std::cout << v5[index] << std::endl;
    }

    for (decltype(v6.size()) index = 0; index < v6.size(); index++) {
        std::cout << v6[index] << std::endl;
    }

    for (decltype(v7.size()) index = 0; index < v7.size(); index++) {
        std::cout << v7[index] << std::endl;
    }

}

3.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
#include <iostream>
#include <vector>
#include <string>
#include <cctype>

using std::vector;
using std::string;

int main()
{
    vector<string> svec;
    string s;
    while (std::cin >> s) {
        svec.push_back(s);
    }
    for (auto &s : svec){
        for (int i = 0; i < s.size(); i++)
            toupper(s[i]);
    }

    for (auto s : svec)
        std::cout << s << std::endl;

    return 0;
}

3.18:

不合法,ivec没有元素

可以改成:vector<int> ivec(1);有一个元素,且下标从0开始

3.4.1

image-20240401193843961

3.21:

关键代码:

1
2
for (auto it = v.begin(); it != v.end(); ++it)
    std::cout << *it << std::endl;

3.22:

关键代码:

for (auto it = text.cbegin(); it = text.cend() && !it->empty(); ++it)
	std::cout << *it << std::endl;

3.23:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <iostream>
#include <vector>

using std::vector;

int main()
{
    vector<int> ivec(10, 2);
    for (auto it = ivec.cbegin(); it != ivec.cend(); ++it)
        //注意解引用的时候加括号,这是这道题的考察点
        std::cout << (*it) * 2 << std::endl;

    return 0;
}

3.4.2

image-20240401195458522

3.24:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>

using std::vector;

int main()
{
    vector<int> ivec;
    int i = 0;
    while (std::cin >> i)
        ivec.push_back(i);
    auto beg = ivec.cbegin(), end = ivec.cend();
    for (auto it = beg, eit = end - 1; it <= beg + (end - beg) / 2; ++it, --eit) {
        std::cout << (*it) + (*eit)<< std::endl;
    }

    return 0;
}

3.25:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>

using std::vector;

int main()
{
    vector<int> index(11, 0);
    auto it = index.begin();
    int score;
    while (std::cin >> score) {
        auto it = index.begin();
        it += score / 10;
        (*it)++;
    }
    for (auto temp = index.cbegin(); temp != index.cend(); ++temp)
        std::cout << *temp << ' ';
    std::cout << std::endl;

    return 0;
}

3.26:

在数据量很大的时候可能会出现溢出,而使用减法一定不会溢出,

3.5.1

image-20240401203305661

3.27:

(a)非法,buf_size不是常量表达式 (b)合法

(c)非法,txt_size()返回值不是常量类型 (d)非法,没有空字符的位置

3.28:

sa为10个空字符、ia为10个0、sa2空串、ia2不确定值

3.29:

①不够灵活:大小是固定的不可扩展

②没有API

3.5.2

image-20240401204104668

3.30:

数组索引从0开始,长度为10的数组索引值为0~9,最后取不到10

3.31:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#include <iostream>

int main()
{
    int arr[10] = {};
    for (int i = 0; i < 10; i++) {
        arr[i] = i;
        std::cout << arr[i] << ' ';
    }
    
    return 0;
}

3.32:

关键代码:

1
2
3
4
5
    int arrCopy[10] = {};
    for (int i = 0; i < 10; i++) {
        arrCopy[i] = arr[i];
        std::cout << arrCopy[i] << ' ';
    }

重写:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>

using std::vector;

int main()
{
    vector<int> ivec(10, 0);
    for (int i = 0; i < ivec.size(); i++) {
        ivec[i] = i;
        std::cout << ivec[i] << ' ';
    }
    std::cout << std::endl;
    vector<int> ivec1 = ivec;
    for (auto a : ivec1)
        std::cout << a << ' ';
    
    
    return 0;
}

3.5.3

image-20240405210354438

3.34:将p2赋值给p1,p1或p2非法则程序非法

3.35:

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

using namespace std;

int main()
{
    int arr[10];
    int *p = arr;
    for (int i = 0; i < 10; i++){
        *p = 0;
        p++;
    }
    for (int i : arr)
        cout << i << endl;

    return 0;
}

3.36:

3.5.4

image-20240406213606032

3.37:无’\0’,循环可能不会停止,可能打印不确定的信息(有风险)。

3.38:两个指针相加得到一个新指针,但是指向的内存地址的内容我们不知道,也不知道有什么用

3.39:

 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>
#include <string>
#include <cstring>

using namespace std;

int main()
{
    string a = "aabb";
    string b = "aabb";
    if (a == b)
        cout << "equal" << endl;
    else
        cout << "not equal" << endl;
    char c[] = {'a', 'b', 'c'};
    char d[] = "abc";   //有空字符'\0'
    if (strcmp(c, d) == 0)
        cout << "equal" << endl;
    else
        cout << "not equal" << endl;

    return 0;
}

3.5.5

image-20240406215144975

3.41:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <iostream>
#include <vector>

using namespace std;

int main()
{
    int arr[] = {10, 20, 30, 40};
    vector<int> vec(begin(arr), end(arr));
    for (int a : vec) {
        cout << a << ' ' << endl;
    }
    return 0;
}

3.42

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int main()
{
    vector<int> vec(3, 2);
    int arr[3];
    for (int i = 0; i < 3; i++)
        arr[i] = vec[i];
    for (int i = 0; i < 3; i++)
        cout << arr[i] << ' ' << endl;

    return 0;
}

3.6

image-20240406221820046

3.43:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
    //版本1
    int ia[2][3] = {{1, 1, 1}, {2, 2, 2}};
    for (int (&a)[3] : ia) {
        for (int b : a)
            cout << b << ' ';
        cout << endl;
    }
    //版本2
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++)
            cout << ia[i][j] << ' ';
        cout << endl;
    }
    //版本3
    for (int (*p)[3] = ia; p != ia + 2; p++) {
        for (int *q = *p; q != *p + 3; q++)
            cout << *q << ' ';
        cout << endl;
    }

3.34:

3.35:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
    for (int_array *p = ia; p != ia + 2; p++) {
        for (int *q = *p; q != *p + 3; q++)
            cout << *q << ' ';
        cout << endl;
    }

    for (auto p = begin(ia); p != end(ia); p++) {
        for (auto q = begin(*p); q != end(*p); q++)
            cout << *q << ' ';
        cout << endl;
    }

4.1.2

image-20240409210203342

4.1:105

4.2:(a)*(vec.begin()) (b)(*vec.begin()) + 1

4.1.3

image-20240409211707659

4.3:

答:我认为可以接受,我们可以人为的多注意,效率必须是C++的优势。

4.2

image-20240409215918411

4.4:

(((12/3) *4) +(5*5)) + ((24%4)/2) 结果为91

4.5:

(a)-86 (b)-18 (c)0 (d)-2

4.6:

a % 2 == 0 ? "偶数" : "奇数"

4.3

image-20240412193835901

4.8:都是先求左侧,如果左侧无法判断结果再求右侧

4.9:先判断cp,如果不是空指针,再判断*cp

4.10:while (cin >> i && i != 42)

4.4

image-20240412195410307

4.13:

(a) i = 3,d = 3.0 (b) i = 3,d = 3.5

4.14:

第一句非法,42是右值。第二句会执行if语句内的内容

4.15:

因为不能将指针赋值给int和double,可以修改为

1
2
3
double dval; int ival; int *pi;
dval = ival = 0;
pi = 0;

4.5

image-20240412201341324

4.17:前置返回将其本身加1后返回,而后置将其加一后返回初始值的副本

4.18:可能会访问不存在的元素

4.19:

(a)ptr不为空且ptr指向的值不为空,并让ptr指向下一个位置

(b)ival不为0且ival+1不为0

(c)非法,因为左右两侧都用到了ival,具有二义性,可以改成vec[ival] <= vec[ival + 1];

4.6

image-20240412202344059

4.20:

(a) 合法,解引用iter并让iter指向下一个位置 (b) 非法,试图将string+1,

(c) 非法,迭代器没有empty成员 (d) 合法,iter指向的string对象的empty成员

(e) 非法,字符串不能++ (f) 合法,先判断iter指向的string对象是否为空再++

4.7

image-20240412203531568

4.21:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    for (int i = 0; i < 10; i++)
        v.push_back(i);
    for (int &x : v) {
        if (x & 1) {
            cout << x << endl;
            x *= 2;
        }
    }
    return 0;
}

4.22:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <iostream>
#include <string>

using namespace std;

int main()
{
    int score = 100;
    string lv;
    lv = (score < 60) ? "fail" : (score > 90) ? "high pass" : (score > 75) ? "pass" : "low pass";
    cout << lv << endl;

    return 0;
}

多个if语句显然更好理解,因为条件运算符包含了多重嵌套,阅读起来比较费力

4.23:

+的优先级大于==和?,所以会先执行s + s[size() - 1] ,不符合题意,并且string不能与char比较,应修改为:

1
2
string s = "word";
string p1 = s + (s[size() - 1] == "s" ? "" : "s");

4.8

image-20240412205248377

4.25: 结果未定义,在对q取反的时候会转换成int类型,而取反后得到一个负数,如果一个对象是带符号的值而且为负,那么这里的移位运算符如何处理符号位依赖于机器

4.26:在不同的机器上int最小位数不一定,可能存在int占16位的情况,导致位数不够

4.27:

(a)3 (b)7

(c)true (d)true

4.9

image-20240412205853373

4.28:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int main()
{
    cout << sizeof(bool) << endl;
    cout << sizeof(char) << endl;
    cout << sizeof(short) << endl;
    cout << sizeof(int) << endl;
    cout << sizeof(float) << endl;
    cout << sizeof(long) << endl;
    cout << sizeof(double) << endl;
    cout << sizeof(long long) << endl;
    cout << sizeof(long double) << endl;
    return 0;
}

4.29:10, 2

4.30:

(a)(sizeof x) + y (b)sizeof(p->men[i])

(c)(sizeof a) < b (d)sizeof(f())

4.10

image-20240414223111309

4.31:后置版本会保存未修改的值并返回,如果不需要则使用前置版本。不需要做改动

4.32:两种遍历数组的方式,iptr是指针,ix是索引

4.33:(someValue ? ++x, ++y : –x), –y

4.11.1

image-20240416201201452

4.34:

4.11.3

image-20240419081328156

5.1

image-20240419082851706

5.2

image-20240419083013270

5.3.1

image-20240419084519303

5.3.2

image-20240419085745522

5.4.1

image-20240419090722127

5.4.2

image-20240419091542899

5.4.4

image-20240420091611659

5.5.1

image-20240420091820819

5.5.2

image-20240420092015672

5.5.3

image-20240420092331123

5.6.3

image-20240420094034595

6.1

image-20240512092438764

6.1.1

image-20240512093306095

6.1.2

image-20240512093452447

6.1.3

image-20240512093811042

6.2.1

image-20240512094506542

6.2.2

image-20240512095229048

6.2.3

image-20240512101027747

6.2.4

image-20240513085139951

6.2.5

image-20240513085429877

6.2.6

image-20240513090452258

6.3.2

image-20240513093038533

6.3.3

image-20240514092047595

6.4

image-20240514094539051

6.5.1

image-20240517075931653

6.5.2

image-20240517080944276

6.5.3

image-20240517081752495

6.6

image-20240517082709971

6.6.1

image-20240517090719222

image-20240517090727292