incline 内联函数
结论:
1) 内联函数在编译时直接将函数体插入函数调用的地方;
2) inline只是一种请求,编译器不一定允许这种请求;
3) 内联函数省去了普通函数调用时压栈,跳转和返回的开销。
介绍:
1)内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等);
2)内联函数是对编译器的一种要求,因此编译器可能拒绝这种请求;
3)内联函数由编译器处理,直接将编译后的函数体插入调用的地方;
4)相比而言,宏代码片段由预处理器 处理,进行简单的文本替换,没有任何变异过程;
5)随着c++编译器的不断进化,现在的c++编译器能够对编译进行优化,即使一些函数没有使用inline关键字声明,也可能被编译器内联编译。另外,一些现在的c++编译器提供了扩展语法,能够对函数体进行强制内联,如:
g++编译器中的attribute((always_inline))属性;
- c++编译器对内联函数的内容复杂度的要求:不能存在任何形式的循环语句,不能存在过多的条件判断语句;函数体不能太庞大;函数内敛声明必须在调用语句之前;
7)内联函数相对于普通函数的优势只是省去了函数调用的压栈,跳转和返回的开销。因此,当函数体的执行开销远大于压栈、跳转和饭后使用的开销,那么内联将变得毫无意义。
函数的默认参数
函数默认参数的规则:
1)只有参数列表后面部分的参数才可以提供默认参数值;
2)一旦在一个函数调用中开始使用默认参数值,那么这个参数后面的所有参数都必须使用默认参数值。否则这样的参数列表
void myPrint(int a = 1, int b = 2, int c)
编译器就会因为最后一个参数不是默认参数而报错。也就是说,在默认参数规则中,如果默认参数出现,则其右边的都必须为默认参数。
函数的占位参数
在函数的参数列表中出现占位参数时,意味着即使函数体无法使用,但是在调用的时候,必须要给足参数的个数,否则就会出错。但其实默认参数和占位参数是要配合在一起使用的。
意义:
1)为以后程序的扩展留下线索;
2)兼容C语言中可能出现的不规范写法。
int func2(int a, int b, int = 0)
{
return a+b;
}
void main()
{
// 如果默认参数和占位参数在一起,都能调用起来
func2(1, 2);
func2(1, 2, 3);
printf("hello world.\n");
}
结论:如果默认参数和占位参数在一起,则函数都可以被调用起来。
函数重载(Function Overload)
函数重载——即用一个函数名定义不同的函数,函数名相同但是参数列表不同。
重载的判断标准
函数重载至少满足其中一个条件:
- 参数个数不同;
- 参数类型不同;
- 参数顺序不同。
- PS:函数的返回值不是函数重载的判断标准!
- 函数重载的注意事项
- 重载函数在本质上是相互独立的不同函数,这在静态编译的过程中就已经确定了;
- 重载函数的函数类型是不同的;
- 函数返回值不能作为函数重载的依据;
- 函数重载是由函数名和参数列表决定的。
当函数默认参数遇上函数重载会发生什么?
当有默认参数时,就不能再创建其他和这个函数除了默认参数之外,相同的参数个数的函数了,否则编译器会报错,因为其他不带默认参数的函数和这个函数一旦被调用会产生二义性。函数重载和函数指针在一起
5.1 函数指针
三种形式:
1)声明一个函数类型
typedef void (myTypeFunc) (int a, int b);
2)声明一个函数指针类型
typedef void (*myPTypeFunc) (int a, int b);
3)定义一个函数指针变量
void (*myVarPFunc)(int a, int b);
当使用重载函数名对函数指针进行赋值时,根据重载规则挑选与函数指针参数列表一致的候选者,并且是严格匹配候选者的函数类型与函数指针的函数类型。