编译和运行程序

C++代码生成可执行文件的过程如下
image.png
编译C++程序时,gcc命令也可以使用,不过要增加-lstdc++选项,否则会发生链接错误。

头文件和std命令空间

随着 C++ 引入了命名空间的概念,计划重新编写库,将类、函数、宏等都统一纳入一个命名空间,这个命名空间的名字就是std。
为了避免头文件重名,新版 C++ 库也对头文件的命名做了调整,去掉了后缀.h
尽量使用这些 C++ 新增的头文件,例如 iostream、fstream、string 等。

new和delete

C++中,新增了两个关键字,new 和 delete:new 用来动态分配内存,delete 用来释放内存。

  1. int *p = new int; //分配1个int型的内存空间
  2. delete p; // 释放内存

如果希望分配一组连续的数据,可以使用new[]

  1. int *p = new int[10]; // 分配10个int型的内存空间
  2. delete[] p;

用 new[] 分配的内存需要用 delete[] 释放,它们是一一对应的。

C++ inline

函数调用是有时间和空间开销的。
程序在执行一个函数之前需要做一些准备工作,要将实参、局部变量、返回地址以及若干寄存器都压入栈中,然后才能执行函数体中的代码;
函数体中的代码执行完毕后还要清理现场,将之前压入栈中的数据都出栈,才能接着执行函数调用位置以后的代码

如果函数体代码比较多,需要较长的执行时间,那么函数调用机制占用的时间可以忽略;如果函数只有一两条语句,那么大部分的时间都会花费在函数调用机制上,这种时间开销就就不容忽视。

为了消除函数调用的时空开销,C++ 提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开。这种在函数调用处直接嵌入函数体的函数称为内联函数(Inline Function),又称内嵌函数或者内置函数。

注意,要在函数定义处添加 inline 关键字,在函数声明处添加 inline 关键字虽然没有错,但这种做法是无效的,编译器会忽略函数声明处的 inline 关键字。

使用内联函数的缺点也是非常明显的,编译后的程序会存在多份相同的函数拷贝,如果被声明为内联函数的函数体非常大,那么编译后的程序体积也将会变得很大,所以再次强调,一般只将那些短小的、频繁调用的函数声明为内联函数。

默认参数

C++中,定义函数时可以给形参指定一个默认的值,这样调用函数时如果没有给这个形参赋值(没有对应的实参),那么就使用这个默认的值。
这个语法和python一样

C++规定,默认参数只能放在形参列表的最后,而且一旦为某个形参指定了默认值,那么它后面的所有形参都必须有默认值。

函数重载

函数的重载的规则:

  • 函数名称必须相同。
  • 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)。
  • 函数的返回类型可以相同也可以不相同。
  • 仅仅返回类型不同不足以成为函数的重载。

其实C++中的函数重载只是编译时根据函数参数列表对函数进行了重命名。
例如void Swap(int a, int b)会被重命名为_Swap_int_int,void Swap(float x, float y)会被重命名为_Swap_float_float。
从这个角度讲,函数重载仅仅是语法层面的,本质上它们还是不同的函数,占用不同的内存,入口地址也不一样。