C++程序的内存空间

  • 代码区:程序代码,常量和常量字符串,相当于汇编的.text段
  • 栈区(runtime):自动变量(局部变量)和形式参数,不可控,容量有限,先进先出,超出作用域自动释放;
  • 堆区(runtime):复杂的数据结构以及手动分配内存(如malloc和new),需要手动释放;
  • 全局区:静态数据(局部static变量,全局static变量)、全局变量。相当于汇编的.data和.bss段

头文件

参考文献:理解 C++ 中的头文件和源文件的作用 | 菜鸟教程 (runoob.com)

  • 分清C++中的定义声明

    • 简而言之,区别在于是否实际分配内存空间
    • 对于基本类型的变量,声明即定义,定义即声明
    • 对于类、struct和函数则不然
  • “一次定义”,但允许多次声明;分别编译,链接时实现互相调用

  • 头文件*.h中只存放:

    • 函数声明:void func(...); //不能带有大括号,那代表定义
    • 变量声明:extern int a; const int a=5; static int a=5; //const和static意味着变量作用域仅限包含它的文件内,不会造成链接时的冲突
    • 类的定义,包括成员变量的定义和成员函数的声明,成员函数的定义可以写在类结构内,作为内联函数;
    • 头文件内不能使用using语句
  • 预处理命令:#ifdef ifndef #undef #endif 的用法:为了防止在头文件相互引用中出现多次定义

  • extern关键字与混合编程

    • extern修饰普通变量或函数:告知编译器此变量/函数定义在其它文件中,要到别处寻找定义;

      extern 与头文件(*.h)的区别和联系 | 菜鸟教程 (runoob.com)

    • extern "C": 混合编程,在C++中以C的方式处理C定义的函数或代码段

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      //fun.c
      #include "fun.h"
      #include<stdio.h>
      void func() {
      ...
      }
      ...
      //fun.h
      #ifdef __cplusplus
      extern "C" void func(); //如果引用头文件的是*.cpp,则使用带extern "C"的函数声明
      #else
      void func(); //如果引用头文件的是*.c,则使用原始由c定义的函数声明
      #endif
      //也可以使用extern "C" {...} 对多行代码进行类似操作
  • C++的标准库函数即是由一系列头文件所定义的,具体包含的所有头文件可见这里

宏定义

控制宏

常量宏

  • 显而易见,不言自明

函数宏

参考文献:[C++] C++中的宏定义详解 - zhizhiyu - 博客园 (cnblogs.com)

  • 基本形式:#define MAX(a,b) (a>b?a:b)
  • 核心是字符替换
  • 一些特殊情况
    • 如果宏标识符出现在引号中则不会被替换
    • 不加括号导致运算顺序出现问题
    • #和##在带参宏中的用法:加引号和衔接
    • C++中预定义的四个宏:__LINE__, __FILE__, __DATE__, __TIME__

A Better C

此部分对应教材第7章

函数重载 Overloading

  • 参数列表不同的同名函数,编译时会生成不同的内部名,对于类成员和全局的同名函数也是如此
  • 不可以使用返回值重载

默认参数和占位符

  • 如:void func(int a, int b=1) {...}

  • 默认参数必须放在参数列表的后部;一旦开始使用默认参数,后面的参数必须都是默认的

    1
    2
    3
    4
    5
    6
    7
    8
    void func(int a, int b=1, int c=2) {
    cout << "Finish" << endl;
    }

    int main(void) {
    func(1, , 3); //错
    func(1, c=3); //错
    }
  • 参数不一定需要标识符, 如:void func(int a, int),第二个参数被称为占位符placeholder

    • 调用时需要给一个值
    • “高瞻远瞩”,给之后的修改留下空间(只需改定义而无需改调用;不想用可以直接在定义处去掉名字)

从Struct到Class

参考文献:C++ class和struct到底有什么区别 (biancheng.net)

主要在于未声明访问标识符时,struct默认公有,class默认私有。