C++函数与C函数的区别
1、函数重载
1、什么是函数重载
在同一作用域下,形参列表不同的同名函数构成重载关系,且不会冲突
调用函数时,编译器会根据实参的数据类型调用合适的函数
2、重载实现的机制
C++代码在编译时函数的参数类型会添加到函数名中,也就是C++的函数名在编译时经历了换名的过程,借助这个方式实现了函数的重载
由于C++和C函数的编译机制不同,所以C++代码不能调用C编译器所编译出的函数。
3、extern “C” {}
功能是告诉C++编译器按照C语言的机制声明函数,这样C++中的代码就可以调用C编译器编译出的函数(C++目标文件与C的目标文件才能合并出可执行文件)。
4、重载和作用域
函数的重载关系一定发生在同一作用域在,不同作用域下的同名函数构成的是隐藏关系。
5、重载函数的调用
当调用重载函数时,编译器会根据实参的数据类型选择合适的重载函数,实参与形参的匹配情况有三种:
1、编译器找到实参与形参完全匹配的函数,编译器会生成调用指令
2、编译器找到多个匹配函数,但没有一个是最佳的,编译器会产生二义性错误。
绝大多数情况下编译器都能找到一个最佳的匹配函数,如果没有,编译器就会进行类型提升,这样备选函数中就有可能有多个可调用的版本,然后二义性错误就产生了。
3、编译器找不到可调用的重载函数,会直接产生错误
6、指针也会影响函数的重载
C++函数的参数如果是指针类型的,编译后就会在产生的汇编文件的函数的末尾添加Px
7、如果参数是指针或引用,是否加const也会影响函数的重载
注意:函数重载是面向对象编程思想的多态(多种形态,根据实参情况对指令做出相应的反应)的体现,具体调用哪个版本的函数实在编译期间就确定了,所以这种也叫编译时多态。

2、默认形参
1、在C++中函数的参数可以设置默认值,在函数调用时,如果调用者没有提供实参,则使用默认的形参
2、如果只一部分参数设置了默认形参,则设置默认形参的靠右排列
3、如果函数的声明与定义分开实现,则只需要在函数声明时设置默认形参。
4、默认形参会影响函数的重载,慎重给重载函数设置默认形参
3、内联函数
1、普通函数会在调用位置生成跳转指令,当执行到调用代码时会跳转到函数所在的代码段位置执行。
2、内联函数就是把函数编译好的二进制指令拷贝到调用位置,也就是没了跳转和返回的过程
3、内联函数的优缺点:
与普通函数相比,内联函数的执行速度更快。
大量使用内联函数会使可执行文件变大,造成冗余。
4、显式内联和隐式内联
显式内联:在函数的返回值类型前加inline(C语言也支持)
隐式内联:结构、联合、类的成员函数会默认优化成内联函数
注意:是否内联由编译器决定(部分编译器没有实现内联的功能)。
5、宏函数在调用时会把函数体直接替换到调用位置,与内联函数一样,用空间来换取时间,宏函数与内联函数的区别(优缺点)?
1、宏函数仅仅是代码替换,不是真正的函数,也就不会有参数传递、入栈、出栈、返回值,而且所有类型都可以使用,但不会进行类型检查,有安全隐患。
2、内联函数是真正的函数调用,函数在调用时会进行参数类型检查、传参、压栈、出栈,也可以有返回值,还可以重载、设置默认形参,但是不能通用了。
6、什么样的情况适合用内联函数
由于使用内联函数会使可执行文件变大,增加内存开销,因此只有调用频繁,且内容短小的函数时候作为内联函数。
调用次数比较少,且内容比较多的函数,内联之后并不能显著提升性能,不足以抵消牺牲空间带来的损失,所以不适合内联。
带有递归特性,和动态绑定特性的函数,无法实施内联,因此编译会自动忽略inline关键字