函数的默认值、重载以及内联函数

一、函数的默认值

给函数形参赋默认值时要注意的三点:

        1.从右向左依次赋默认值


int Sum(int a,int b,int c=10);//正确
int Sum(int a,int b=10,int c);//编译程序报错:“Sum”: 缺少参数 3 的默认参数

 联想记忆:我们都知道实参与形参的匹配是从左到右进行匹配的,当实参不够时,才会看有没有赋默认值,所以默认值是从右到左依次赋予的。

        2.默认值只能赋一次

同一函数可多次声明,但默认值只能赋一次

int Sum(int a,int b,int c=10);
int Sum(int a,int b,int c=10);//编译程序报错:“Sum”: 重定义默认参数 : 参数 3

        3.一般在声明中赋默认值

若声明时赋了值,则函数定义时不能再次赋值;

int Sum(int a,int b,int c=10);
int Sum(int a,int b,int c=10)//程序编译报错“Sum”: 重定义默认参数 : 参数 3
{
	return a+b+c;
}
int main()
{
	Sum(10,20);
	return 0;
}

若声明时没赋值,则在定义函数时赋值正确,但是此时若定义点放在主函数后面,如下:则错误。

int Sum(int a,int b,int c);
int main()
{
	Sum(10,20);
	return 0;
}
int Sum(int a,int b,int c=10)
{
	return a+b+c;
}

注意:若调用点给了函数实参,实参会替代默认值。

如:

int Sum(int a,int b,int c=10)
{
	return a+b+c;
}
int main()
{
	int tmp=Sum(5,10,20);
	printf("%d\n",tmp);//打印结果:tmp=35
	return 0;
}

 若调用点给实参值的个数少于函数定义时形参个数,并且函数已经赋过默认值,则若调用点所给实参值的个数大于或等于(小于会报错)函数的参数总个数减已经被赋过默认值的形参个数,则将实参值(从左向右)依次分配给未赋默认值的形参(从左向右)。

 二、函数重载

1.C语言与C++中函数符号的生成规则:

         (1)C语言中函数符号的生成只和函数名有关,不能定义两个函数名相同的函数

         (2)C++中函数符号的生成和函数原型有关,包括函数的返回值类型、函数名、形参列表(类型,个数,顺序)

C++中生成的函数符号示例如下:

 YA:__cdecl调用约定,默认

YG:__stdcall

YI:__fastcalll

参数类型及返回值类型对应生成的符号:

_N--》bool

H--》int

N--》double

2.重载决议:

       (1)不能让编辑器产生二义性

                    重载决议时,若都不匹配,编译器会产生二义性,所以会报错。注意:匹配时char类型与int类型的转换,char类型是迷你的int类型,二者可无条件自由转换(可参考隐式转换图)。 

        (2)函数重载不依赖返回值:这是因为,在编译阶段,调用点匹配时只能看见函数名和形参列表,看不见函数的返回值类型,所以只有函数返回值类型不同是不能构成重载的。

3.函数重载的三要素:

        (1)同作用域下(才能进行重载)

        (2)同名 

        (3)参数不同

注意:C语言不支持重载机制,重载是C++中的,这是由二者函数符号的生成规则而导致的,C++中函数符号的生成和函数原型包括返回值、函数名、形参列表(类型、个数、顺序)有关,函数的形参为函数重载提供了支持。

 三、内联函数     

 函数前用关键字inline修饰的函数即为内联函数,编译阶段在函数调用点直接展开代码,没有开栈清栈开销。

1.内联函数的优缺点:

        (1)优点:可以提高效率

        (2)缺点:以代码膨胀为代价(浪费空间),即以空间换时间

    所以,如果代码的执行开销  <  函数的开栈、清栈开销 ,选择使用内联函数 

2.内联的注意事项:

        (1)内联函数写在头文件中

        (2)内联只在Release版本生效,在Debug版本不生效

        (3)含有递归、循环、switch的内联函数,编译器会当普通函数处理,内联只是给编译器的建议

        (4)内联是基于实现的关键字。在声明点加inline编译器会忽略,只能加在定义点,加在声明点是无效的

(5)内联函数是不生成符号的

注意:内联函数不是在调用时发生控制转移,而是在编译时将函数题嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。

3.内联函数与static修饰的函数都是在本文件可见,但二者有一个最大的区别就是:

        内联函数没有栈帧开辟和清理的开销(不开栈,也就不用清栈)

        static修饰的函数有开栈和清栈的开销

二者还有一个区别就是其导致本文件可见的原因不同:

前者内联是因为编译阶段在函数调用点直接展开代码而导致(编译阶段是以一个源文件为编译单元)

而后者是因为static修饰的函数是local属性。

4.inline与宏的区别

inline:编译阶段处理        有类型检查              安全

宏:    预编译阶段处理     无类型检查             不安全

inline是一种更安全的宏

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值