C++primer第五版第二章学习笔记

本文详细介绍了C++编程的基础知识,包括基本内置类型、引用、指针、const限定符、类型别名和auto类型的应用。同时,还讨论了自定义数据结构的创建和作用域管理。内容涵盖了从简单数据类型到复杂数据结构的全面指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 基本内置类型:算数类型、空类型

  2. 算数类型:整型、浮点型

  3. short、int、long、long long的区别:存放数据时所占用的内存大小不一样,sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

  4. signed和unsigned的区别:signed可以表示正负数或0,unsigned只能表示非负数

  5. float和double的区别:float的精度小于double

  6. 类型转换可能会导致的问题:溢出、数据截断

  7. 避免无法预知以及依赖于实现环境的行为

  8. 不要混用signed和unsigned的类型

  9. signed 转 unsigned超出范围时会进行取模赋值,如将 -1 赋值给unsigned char类型的变量,则最后的赋值结果是:-1 % 2^sizeof(unsigned char)

  10. 字符串默认最后有一个结束符 '\0',所以长度会比字面值的长度多1

  11. 变量定义的形式:类型 变量名1, 变量名2;

  12. 列表初始化:

    // 如果使用列表初始化且初始值存在丢失信息的风险时,编译器会报错
    int i = 0;
    int i = {0};
    int i{0};
    int int(0);

  13. 变量定义时如果没有初始化,则会被默认初始:

    • 函数体外的变量会被初始化为0
    • 函数体内的未初始化的变量则不会被默认初始化
    • 未被初始化的内置类型变量的值是未定义的
    • 类的对象如果没有显示地初始化,则其值由类确定
    • 如果试图拷贝或以其他形式访问未定义的值,则会引发错误

  14. c++支持分离式编译机制,允许将程序分割为若干个文件,每个文件可被独立编译。为了支持这个机制,c++将声明和定义区分开来

  15. 声明和定义:

    • 声明使名字为程序所知,一个文件如果想使用别处定义的名字,则必须包含对那个名字的声明。
    • 声明规定了变量的类型和名字,这点和定义是相同的,但是仅声明一个变量的话需要在变量名前加上关键字extern,而且不要显示地初始化变量。
    • 定义负责创建和名字关联的实体、还会申请存储空间,也可能会为变量赋初始值
    • 变量只能被定义一次,但是可以被声明多次
    • 任何包含了显示初始化的声明会变成定义,不管是否加了extern
    • 在函数体内部初始化一个由extern标记了的变量将会引发错误 e.g.
         extern int i; // 声明i而非定义 i
         int j;        // 声明并定义 j
  16. 作用域:

    #include <iostream>
    using std::cin;
    using std::cout;
    using std::endl;
    
    int reused = 42; // 全局作用域
    int main()
    {
        // 块作用域,声明周期到main函数结束为止
        int unique = 0;
        // 使用的是全局作用域中的reused
        cout << reused << " " << unique << endl;
    
        // 定义一个块作用域内的变量reused,覆盖掉全局作用域中的同名变量
        int reused = 0;
        // 使用的是块作用域中的reused
        cout << reused << " " << unique << endl;
    
        // 显示地访问全局作用域中的reused
        cout << ::reused << " " << unique << endl;
    
        return 0;
    }

  17. 复合类型:引用和指针

  18. 引用

    • 引用不是对象,只是一个已经存在的对象的别名,所以不能定义引用的引用
    • 引用必须被初始化,且初始值必须是一个对象(非字面值,常量引用可以使用字面值初始化),初始化之后无法被重新与其他的对象进行绑定
    • 一般情况下引用的类型需要与绑定的对象的类型一致,两种例外情况如下:
      • 引用的类型与对象的类型存在继承关系:SubClass sub; Parent &p1 = sub;
      • 引用的类型与对象的类型含有一个可接受的const类型转换规则:
        /**
         * 下面的代码编译器会将其优化为: 
         * double dval = 3.14; 
         * const int temp = dval;
         * const int &ri = temp;
         * 实际使用中避免这种情况。
         */
        double dval = 3.14; 
        const int &ri = dval;
  19. 指针,建议初始化所有的指针

    • 指针本身是一个对象,允许指针赋值和拷贝
    • 指针不要求在定义时就初始化
    • 函数体内的指针未初始化时的值也是未定义的
    • 指针存放的是指定对象的地址,获取对象的地址可以使用取地址符 &
    • 一般情况下引用的类型需要与绑定的对象的类型一致,两种例外情况与引用的相同
    • 无效指针(野指针):值是未定义的指针
    • 空指针:没有指向任何对象的指针,生成空指针的方法:
      int *p = nullptr;
      int *p = 0;
      // #include cstdlib
      int *p = NULL;
    • 通过解引用符 * 来利用指针访问对象,给解引用的结果赋值等价于给指针所指的对象赋值
    • 非0的指针对应的条件值都是true
    • void指针可以存放任意对象的地址,但是因为无法确定void所指向的对象是什么类型以及可以对该对象进行什么操作,所以不能直接操作void*所指向的对象
    • 二级指针:指向指针的指针
    • 引用不是对象,所以不能定义一个指向引用的指针
  20. const限定符

    • const限定的变量不能进行更改,所以必须初始化
    • 默认状态下,const对象仅在文件内有效,编译器会将const对象替换成初始化时的值,如果要在多个文件共享该对象,则需要用到extern
    • 常量引用可以指向常量引用与非常量引用,但是非常量引用不能指向常量引用,常量引用不能重新赋值,常量引用可以使用字面值进行初始化
    • 常量指针可以指向常量对象与非常量对象,但是非常量指针不能指向常量对象,常量指针可以重新赋值,但是不能通过常量指针修改其指向的对象

  21. 类型别名

    typedef double my_double; // mydouble md = 3.14159;
    type double *my_dp; // my_dp dp = &md;
    using SI = Sales_item; // SI book;

  22. auto类型

    • auto i = 1; 编译器会自动分析推断 i 的类型
    • auto定义的变量必须要初始化
    • auto在一条语句上声明多个变量时,该语句的所有变量的初始基本数据类型都必须一样:auto i = 0, b = 1;
    #include <iostream>
    
      int main()
      {
          const int i = 1;
          // j 是int,并不是const int
          auto j = i;
          // k 是const int
          const auto k = j;
          // m 是const int*,而不是int*
          auto m = &i;
          // n 是const int&,而不是int&
          auto &n = i;
    
          return 0;
      }

  23. 自定义数据结构

    struct A {
        // 类体
    } variable1, variable2;
    
    // 等价于:
    struct A {
        // 类体
    };
    A variable1, variable2;

  24. 文件头保护符:#ifndef-#endif,#ifdef-#endif,无视作用域的规则,必须唯一
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值