内联函数
预定义宏的概念是用内联函数来实现的,内联函数本身也是一个真正的函数。
内联函数具有普通函数的所有行为,唯一不同之处在于内联函数会在适当的地方像预定义宏一样展开,不需要函数调用的开销。
1.内联函数的声明和定义需要都加上inline关键字
2.类里的成员函数都隐式添加了inline关键字
3.内联仅仅是给编译器建议,编译器不一定会接受,即使没有将函数声明为内联函数,编译器也可能将此函数做内联编译
- c++内联函数的限制,以下情况编译器不会将函数进行内联编译:
- 内联函数不能存在任何形式的循环语句
- 不能存在过多的条件判断语句
- 函数体不能过于庞大
- 不能对函数进行取地址操作
- 宏缺陷
//宏缺陷1:需要加括号保证运算完整
#define MYADD(a,b) ((a)+(b))
void test0301() {
int a = 10;
int b = 20;
int ret = MYADD(a, b) * 20;
cout << ret << endl;
}
//宏缺陷2:即使加了括号,有些运算依然与预期不符
#define MYCOMPARE(a,b) ((a)<(b)?(a):(b))
void test0302() {
int a = 10;
int b = 20;
int ret = MYCOMPARE(++a,b);
cout << ret << endl;
}
函数的默认参数和占位参数
//函数默认参数
int func0401(int a=10, int b=10) {
return a + b;
}
1.函数的设置默认参数时最右的参数必须设置默认值,调用函数时参数从左往右匹配,所有在实参数少于形参数时,右边未匹配到实参的形参使用默认值
2.函数的声明和实现只能有一个提供默认参数,不可以同时加默认参数
//占位参数:只写一个类型进行占位,调用时必须传入占位参数
void func0402(int a, int=1) {
}
void test0402() {
func0402(2,1);
}
函数重载
- 函数重载条件
- 在同一作用域
- 函数名称相同
- 参数个数、类型、顺序不同
- 返回值不可以作为函数重载的条件
- 函数重载需要避免二义性:
加const和不加const的引用可以重载;
//2和3可以重载,1和3不可以重载
//1
void func0501(int a) {
cout << "func0501(int a)调用" << endl;
}
//2
void func0501(int &a) {
cout << "func0501(int a)调用" << endl;
}
//3
void func0501(const int &a) {
cout << "func0501(int a)调用" << endl;
}
有默认值的多参和少参要避免二义性;
//以下2个函数不能重载
void func0501(int a, int b = 10) {
cout << "func0501(int a)调用" << endl;
}
void func0501(int a) {
cout << "func0501(int a)调用" << endl;
}
extern “C”
c++调用c语言函数时需要添加extern "C" void func();
声明,因为c++中存在函数重载会对函数名进行修饰,因此会找不到原名函数,c语言没有函数重载
//告诉编译器show函数用c语言的方式做链接
extern "C" void show();
void test0601() {
show();//部分编译器修饰后的实际函数名为_Z4showv:c++函数重载会修饰函数名,但show是c语言文件链接失败
}
在c语言头文件中声明extern "C"也可以让c++使用c语言程序
#ifdef __cplusplus
extern "C" {
#endif
#include<stdio.h>
void show();
#ifdef __cplusplus
}
#endif