C++primer学习笔记_第三章

该文只是我的学习笔记,不保证正确性,仅供参考。如果发现错误,欢迎指出来。

第三章

1.命名空间的using声明

  • 一个using只能声明一条语句
using std::cin;  // 正确
using std::cout, std::endl;  // 错误 
  • 可以直接声明命名空间
using namespace std;

2.标准库类型string

2.1.初始化对象

  • 初始化的几种特殊写法
string s1("value");
string s2(n, "c");  //n个"c"相连的字符串

2.2.string对象上的操作

2.2.1.string读取注意事项

  • cin每次读取以第一个不是空格的字符开始,遇到第一个字符为止,代码如下:
string line;
cin >> line;  // 输入"hello world"
cout << line << endl;  // 输出"hello"
  • 注意到程序输入1后,输出会换行两次,我的猜测是输入1后点击换行,被getline接受到,getline读取空行。
int main() {
    int choose;
    string content;
    cin >> choose;
    if (choose == 1) {
        while (getline(cin, content)) {
            cout << content << endl;
        }
    } else if (choose == 2) {
        while (cin >> content) {
            cout << content << "*****" <<endl;
        }
    }
    return 0;
}

输入输出情况

1

afaf afa af
afaf afa af
af
af

2.3 处理string字符

2.3.1 字符类型判断

  • primerC++的82页(本地跳转108页)
  • 字符类型的判断仅限与char类型

2.3.2 for循环的另一个用法

// 类似python的for循环
for (declaration: expression) {
    statement
}
  • 例子
#include <iostream>
#include <string>

int main() {
    std::string str = "hello world";
    for (auto a: str) {
        std::cout << a << std::endl;
    }
    return 0;
}
  • 注意for循环string类型得到的是char类型

3 标准库类型vector

3.1 vector的一些注意事项

  • vector是对象的容器,不是容纳引用
  • 花括号构建,如果花括号中的值无法初始化vector,就会往构建vector方面解释
vector <string> v5{"hi"};  // 正确,初始值为hi
vector <string> v6("hi");  // 错误
vector <string> v7{10};  // 正确,10个容量的空vector
vector <string> v8{10, "hi"};  // 正确,10个“hi”的vec
  • 在使用范围循环语句时(类似python的for循环语句时),不要使用使容器中元素数量变化的方法

for范围循环,冒号前面的那个变量必须是新定义的(至少我到目前遇到的情况是这样的)

3.2 定义和初始化vector

  • 初始化的方法在书本87页(跳转113页)

花括号和圆括号的区别

3.3 vector对象的操作

  • 除非vector中的值都一样,不然初始化时定义容量性能反而会更差。
  • push_back将值加入vector的尾部(如同python的append)
  • 一些vector的操作91页(跳转117页)
  • vector.size()返回的是vector<type>::size_type对象。记住尖括号中的type类型不可丢弃。
  • vector不能使用下标来添加元素

4 迭代器

4.1 迭代器的使用

  • 如果容器为空,则begin和end返回的是同一个迭代器,都是“尾后迭代器”
  • end迭代器指向的是尾后,而不是最后的一个元素
  • for循环中尽量使用!=和,因为所有迭代器都定义了!=和,而有些迭代器没有定义<、>之类的符号
  • 迭代器的类型是iterator和const_iterator
  • 任何会使迭代器容量发生改变的操作都会使迭代器失效

4.2 迭代器的运算

  • 计算表99页(跳转125页)
  • 迭代器减去迭代器如it1 - it2的1结果类型为diffience_type,是带符号类型的

5 数组

5.1 定义和初始化内置数组

  • 数组的大小不可变,虽然不灵活,但在某些情况下性能更好
  • 数组形式a[b],b也是类型的一部分且为常量
  • 数组不能将内容拷贝给其他数组初始化和为其他数组赋值
  • 数组声明含义:从内向外,从左向右
int *ptrs[10];             // ptrs是含有10个指针的数组
int &refs[10] = /*?*/;     // 错误,数组内都应该是对象,没有引用的数组 
int (*Parray)[10] = &arr;  // 由内而外的理解,是给指向10个整数的数组的指针
int (&arrRef)[10] = arr;   // 是个10个整数数组的引用
int *(&arry)[10] = ptrs;   // 10个指针的数组的引用

5.2 数组元素的访问

  • 数组下标一般类型为size_t,在头文件<cstddef>或<stddef.h>中
  • 数组下标也可以直接使用字面值 、int、unsigned等类型

5.3 数组与指针

  • 有些情况下数组名常常看作一个指针

    int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    auto ia2(a)  // 等于 int *ia2 = &ia[0]; 所有ia2是一个指针
    
  • decltype(ia)表示的是10个整数的数组

  • 数组的指针支持运算,是迭代器

  • <iterator>中的begin()end()函数分别返回数组的首元素指针和尾后指针(对string、vector类型同样适用)

  • auto n = end(arr) - begin(arr);  // n 为ptrdiff_t类型,也是<cstddef>库中的类型,可为负值
    
  • 指向先定义的变量的指针大于后定义的变量(变量类型要一致)

    int main() {
        system("chcp 65001");
        int a = 100, *p2 = &a;
        int b = 40, *p = &b;
        if (p2 > p) {
            cout << "*p2大于*p" << endl;
        } else {
            cout << "*p2小于*p" << endl;
        }
    }
    

5.4 C风格字符串

  • 在<cstring>中的一些函数

    1. strlen(p) 返回p的长度,空白符不包含在内
    2. strcmp(p1, p2) 如果p1和p2相等,返回0; 如果p1大于p2,返回正值; 如果p1小于p2,返回负值
    3. strcat(p1, p2) 将p2附加到p1上,返回p1
    4. strcpy(p1, p2) 将p2的内容拷贝到p1上去
  • string str1  = "A example";
    string str2  = "a example";
    char   ch1[] = "A example";
    char   ch2[] = "a example";
    if (str1 < str2) \*...*\;     // 比较的是字符串大小
    if (ch1 < ch2)   \*...*\;     // 比较的是指针大小
    

5.5 旧代码接口

  • vector与数组:

    初始化时可以这么写:

    int num[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    vector<int> v1(begin(num), end(num));  // vector中的数据位置与数据内容与数组num中的数据相同
    vector<int> v2(num + 2, num + 6);      // vector的内容为{2, 3, 4, 5}(包括开头,不包括结尾)
    

5.6 多维数组

  • 严格来讲c++没有多维数组。本节讲的多维数组实质上是指数组的数组。

  • 对与多维数组的范围for循环,需设为引用,因为不设为引用,控制变量就为指针,而指针不能进行接下来的for范围循环

    int a[10][20][30] = {1};
    for (int (&x)[20][30]: a) {
        for (int (&y)[30]: x) {
            for (auto z: y) {
                cout << z << endl;
            }
        }
    }
    
  • int *p[4];  // 整形数组的指针
    int (*p)[4];  // 指向含有4个元素的整形数组
    
上一篇:Postman的基础使用


下一篇:C Primer Plus 第2章 C语言概述-编程练习