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

来源:互联网 发布:家具绘图软件 编辑:程序博客网 时间:2024/05/22 04:47
  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 cstdlibint *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,无视作用域的规则,必须唯一
0 0
原创粉丝点击