深入理解 C/C++(Olve Maudal & Jon Jagger)笔记

  1. main无显式返回时,程序返回值为最后的函数调用的返回值。
  2. 对于函数定义void func(),C语言表示func接受任意数目、任意类型的参数;C++语言表示不接受参数,相当于void func(void)。若C语言希望函数不接受参数,需要显示声明为void func(void)
  3. 对于全局&局部static变量,在C语言中初始化为0;在C++中初始化为它的默认值(内置类型为0)。对于auto变量,不进行初始化(对函数内的auto变量进行初始化影响性能?),但deubg(非优化)时可能会被初始化为0;当连续多次对包含auto变量的函数进行调用时,变量可能每次分配到相同内存(Execution Stack or Activation Frames)。
  4. 函数外部非static变量自动初始化为0,且全局可见(链接器允许其它对象文件访问该变量);函数外部static变量自动初始化0,仅本编译单元可见。
  5. C/C++在一个序列点(Sequence Point)对一个变量只能更新一次,a = a++后a的值undefined。
  6. C/C++表示式求值顺序unspecified,如int a = b() + c()b()c()调用顺序unspecified。
  7. 序列点(Sequence Points):程序执行中,该点之前的所有副作用已经结束,并且后续的副作用还没发生。
    int a=41; a++; printf("%dn", a);           // 42
    int a=41; a++ & printf("%dn", a);          // undefined
    int a=41; a++ && printf("%dn", a);         // 42
    int a=41; if (a++ < 42) printf("%dn", a);  // 42
    int a=41; a = a++; printf("%dn", a);       // undefined
    
    a = a++       // undefined
    a + a++       // undefined
    
  8. 字边界对齐
    // 32位下
    // C语言 非C++
    struct X {
        int a;
        char b;         // 对齐到边界
        int c;
    };
    sizeof(struct X)    // 12
    
    struct X {
        int a;
        char b;         // 对齐到边界
        int c;
        char d;         // 对齐到边界
    }
    sizeof(struct X)    // 16
    
    struct X {
        int a;
        char b;
        char d;         // b c 共同对齐到边界
        int c;
    };
    sizeof(struct X)    // 12
    
  9. The Spirit of C
      Trust the programmer
      Keep the language small and simple
      Provide only one way to do an operation
      Make it fast, even if it is not guaranteed to be portable
      Maintain conceptual simplicity
      Don’t prevent the programmer from doing what needs to be done
  10. 在C++中,Plain Old Data(POD)结构相当于C语言中的结构体。
  11. 没有继承,只有普通成员函数时,不改变sizeof(struct X)大小。
    C++语言的

    struct X {
        int a;
        void func(int v);
    };
    

    相当于C语言的

    struct X {
        int a;
    };
    void func(struct X *this, int v);
    
  12. Rule of Three:析构函数、复制构造函数和赋值操作符,当自定义实现了其中之一时,其它两个也必须重新实现,而不能使用编辑器默认提供的实现。
  13. 类成员变量应当在初始化列表中进行初始化,而不是让其自动初始化后,再在构造函数体中对其进行赋值。且初始化列表中成员变量出现的顺序应与类中定义顺序一致。
  14. 虚函数表:子类虚函数表中包括了继承自父类的虚函数、重写父类的虚函数及自身定义的虚函数。

发表评论

电子邮件地址不会被公开。