低调小萱

导航

 

C++ primer 读书笔记

第一章

  1. STL( standard library)是c++最常用的标准库

  2. 命名空间可以帮助我们避免不经意的名字定义冲突,以及使用库中相同名字导致的冲突。

  3. c++ 的注释为 /* ~~~ */ ,但是为了方便,每一行开头都加上星号。另一种注释为 // 一般用于单行注释

  4. 在c++中,通过定义一个来定义自己的数据结构,一个类定义了一个类型以及相关联的一组操作。类特性是c++最重要的特性之一。

  5. 成员函数

    1. 成员函数是定义为类的一部分函数,有时候也被称为方法
    2. item.isbn() 名为item的对象的 isbn 成员

第二章

2.1 内置基本类型

  1. 大多数计算机以2的整数次幂个比特作为块来处理内存,可寻址的最小内存块成为 字节(byte) ,存储的基本单元称为 字(word) 通常由几个字节组成,

  2. c++中,一个字节要能至少容纳机器基本字符集中的字符,大多数机器的字节由8比特构成。字则由32或64比特构成,也就是4或8字节。

  3. 符号类型

    1. 带符号(signed) 可以表示正数,负数,0 无符号(unsigned) 表示大于等于0的值。

    2. int, short long ,long long都是带符号的。但是可以通过前面加 unsigned 可以变成无符号类型

    3. 字节型符号有三种:char、signed char、unsigned char。具体含义看编译器所以不安全。一般要人为指定。

    4. 不同数据类型会影响运算速度。所以程序员应该尽可能明确的指定变量的数据类型。

    5. 程序可以完成类型转换。例如将 0 转化为 true ,但是这样会依赖环境和编译器。并不建议使用

    6. 切记混用带符号类型和无符号类型。因为带符号数回自动的转化为无符号数。从而影响程序运行。

    7. 字符 和 字符串 字面值。 字符:"A", 字符串:"hello world",字符串实际上一个数组(array)。在末尾有一个空字符作为转义符。

2.2 变量

  1. 声明和定义

    1. 声明(declaration) 使得名字为程序所知道,一个文件如果想使用别处定义的名字,则必须包含对那个名字的声明

    2. 定义(definition) 创建与名字关联的实体

    3. 声明只是让程序知道这个名字,定义则会开辟一块内存空间,或者赋一个初始值,定义只能出现在一个文件中,但是声明可以在多个地方

  2. 作用域

    1. 一般是指一个函数或者变量作用的地方。通常以花括号为分割。

    2. 同一个名字在不同的作用域中可能指向不同的实体

    3. 建议在使用变量的附近定义变量,能够规避作用域冲突的问题。

    4. 嵌套作用域: 作用域中一旦声明了某个名字,则所有嵌套的作用域都能访问。同时也允许内层作用域中重新定义已有的名字

2.3 复合类型

  1. 引用(reference)

    1. int ival = 1024;
      int &refVal = ival;	// refVal 指向了 ival
      
    2. 引用是为对象起了另一个名字。通常用 &d 来定义。 d 是变量名

    3. 引用必须被初始化 因为定义引用的时候,是将 引用 初始值绑定在一起,而不是 拷贝 一份。如果没有初始化就没有初始值。没得绑

    4. 引用只是名字不是对象。不可有 引用的引用

  2. 指针(pointer)

    1. int *ip1, *ip2; // ip1是int型指针
      int ival=42;	
      int *p = &ival;	// p存放ival的地址, p是指向ival的指针。
      
    2. 指针和引用类似但是并不相同

      1. 指针本身也是对象,可以赋值和拷贝,所以有 指针的指针 这种操作。
      2. 指针定义的时候可以不用赋初值,同样不初始化也会有一个不确定的值。
      3. 一般来说指针是存放变量的地址,所以用 & 取址符来得到变量的地址。
    3. 指针的状态

      1. 指向一个对象
      2. 指向紧邻对象所占据空间的下一个位置
      3. 空指针,没有指向任何对象
      4. 无效指针,其他情况
    4. 利用指针访问对象

      1. 与取址符对应的是 解引用符(*)

      2. int a = 42;
        int *p = &a; // 指针p, 存放着变量 a 的地址
        cout << *p;	// 由解引用符 * , 解析指针的地址找到变量a,输出a的址。
        
      3. // & 和 * 的多重含义
        int i = 42;
        int &r = i; 	// & 紧随着类型名出现,r是一个引用
        int *p;		    // * 紧随这类型名出现,p是一个指针
        p = &i; 		// & 出现在表达式中,是一个取址符
        *p = i; 		// * 出现在表达式中,是一个解引用符
        int &r2 = *p; 	// & 是生命的一部分, *是一个解引用符
        
    5. 空指针

      1. int *p = nullptr; //c++11 新引入
        int *p2 = 0;	// p2被初始化,但是没有指向任何对象
        
      2. 指针一定要初始化。最好先定义了变量再定义它的指针,最次也要是定义为空。 不要她成为野指针,不然内存有东西会让人很苦恼

    6. void*

      1. 是一个特殊的空指针。只代表一个内存对象,不清楚内存里的数据是什么类型

2.4 const限定符

  1. 常量的定义 const int i = 2

  2. 默认情况下,const对象被设定仅在文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。

    如果想在多个文件之间共享const对象,必须在变量的定义之前添加 extern 关键字

  3. 指针和const

    1. 如果想定义一个 指向常量的指针(pointer to const) ,只能使用常量指针

    2. const double pi = 3.14;
      double *ptr = &pi; 			// 错误:ptr只是一个普通的指针
      const double* cptr = &pi; 	// 正确: cptr也是个常量指针
      double* const cur = &pi;	// cur一直指向pi
      constexpr int *q = a 		// constexpr 限定符只对指针有效
      // 疑惑 上面两句有什么区别呢
      
  4. 顶层const TODO

  5. // TODO

2.5 处理类型

  1. 类型别名:让复杂的类型起一个简单的名字。有两种写法

    1. // 传统方法 typedef
      typedef doubel wages;		// wages 是 doubel 都同义词
      typedef wages base, p;		// base 是 double 的同义词,p 是 double* 的同义词
      
      // 新标准方法  别名声明 using
      using SI = Sales_item;		// SI 是 Sales_item 的同义词
      
  2. auto类型

    1. 让编译器决定一个变量的类型
    2. TODO:留着进阶 第二遍的时候再看
  3. decltype 类型指示符:希望从表达式的类型推断出要定义的变量的类型。但是不想用该表达式的值初始化变量

    decltype(f()) sum = x;  	// sum的类型就是函数 f 的返回类型
    
    1. TODO:留着进阶

2.6 自定义数据结构

  1. 定义 Sales_data 类型

    1. struct Sales_data{
          std::string bookNO;
          unsigned units_sold = 0;
          double revenue = 0.0;
      };
      Sales_data accum, trans, *saplesptr;
      
  2. 使用 Sales_data 类

  3. 编写自己的头文件

    1. 一般不在函数体内定义类,而是在函数体外。
    2. 类通常被定义在头文件中,且头文件的名字应该与类名一样
    3. 头文件通常包括那些只被定义一次的实体。如 类、const、constexpr等
    4. 头文件之间可以互相包含
  4. 预处理器

    1. 头文件保护符,用于解决多次重复包含的问题
    2. #defin#ifdef TODO:进阶内容

第三章:字符串、向量和数组

3.1 命名空间的using声明

  1. 使用不同命名空间的一种方法 using

  2. using namespace std;	// from std import *
    using std::cin;		// from std inmport cin
    
  3. 头文件不应该包含 using 声明,头文件的内容会拷贝到所有引用他的文件中去。

3.2 标准库类型 string

  1. string 表示可变长的字符序列。

  2. 定义和初始化 string 对象。 string是一个类,实例一个string有多种方式

  3. string 对象上的操作

    1. ![](D:\python-learning-team\杨子萱\图片\表3.2 string的操作.PNG)

    2. 使用 getline 读取一整行。使用ciny读取时遇到空格就停止了,getline遇到换行符才停止

    3. string line;	// 实例化一个string对象 line
      line.size();	// 返回 line 的长度
      line::size_type	// 疑问
      
    4. string 比较

    5. string 赋值

    6. string 相加

    7. 字面值和 string 对象相加

    8. 字面值和string可以想加,因为c++自动转化了类型。但是字面值和字面值不能想加。为了兼容c,字面值不是string类型

    9. string s1 = "hello", s2 = "world";
      string s3 = s1 + "," + s2 + "\n";
      // 当string和字符字面值相加时,确保每个加号(+)两侧运算对象至少一个是string
      string s4 = s1 + ",";		// 正确
      string s5 = "hello" + ",";	// 错误
      string s6 = s1 + "," + "world";	//正确 
      string s7 = "hello" + "," + s2; 	// 错误
      
    10. 如何处理 string 中的每个字符?

      1. for (declaration : expression)
        	statement
        // expression 是一个对象,表示一个序列。
        // declaration 定义一个变量,用于访问序列中的基础元素
            
        string str("hello world!");
        for (auto c : str)
            cout << c << endl;
        
    11. 使用for语句改变字符串中的字符

      1. 我们想改变字符串中的值,要把循环变量定义成引用类型才行。引用则意味着这个变量被绑定到了序列的每个元素上。

      2. string str("hello world");
        for (auto &c : s)
            c = toupper(c);
        cout << s << endl;
        
    12. 部分字符 下标运算符([ ]) eg: str[0]。必须大于0,小于s.size() 不然会超出内存

3.3 标准库类型 vector

posted on 2021-07-25 22:28  低调小萱  阅读(94)  评论(0)    收藏  举报