函数默认值,内联函数,函数重载。

内联函数:

使用原因:为了解决频繁调用大小函数大量消耗栈(栈内存)空间的问题,引入了inline修饰符。
如:

inline int Max(int a ,int b)
       {
            return a+b;
       }

内联函数的处理方式就是直接在函数的调用点,直接将代码展开,就相当于直接把这个函数的函数体,直接复制了一份放在了当前调用点的位置,这样做的目的就是减少了函数调用中的开栈和清栈。
如下:
左边为普通的函数调用 ,右边为引用函数的调用
请添加图片描述
普通函数调用点,实参压入栈中,然后处理函数体。
内联函数调用点,函数没有开辟栈帧和清栈,函数直接在调用点展开。(主要开销是)现场保护和现场恢复
内联函数内部尽可能只有 的单一语句(不能包含条件语句和循环语句)
内联函数和普通函数的区别

  1. 内联函数在调用点代码直接展开,没有开栈和清栈的开销。普通函数有。
  2. 如果内联函数的函数体过于复杂,会被当做普通函数处理。
    内联函数和static函数的区别
  3. static修饰的函数处理机制,只是将函数的符号变为局部符号,函数的处理机制和 普通函数相同。也有开栈和清栈。
  4. inline函数是在代码调用点直接展开导致函数本文件可见,static函数本文件可见是因为static的修饰,是全局符号变为局部符号。
    内联函数和宏的区别
  5. inline函数的处理机制是在编译阶段,有安全检查和类型检查
    宏是在预编译阶段,简单的文本替换。
  6. inline函数是更安全的宏。不生成符号

不是所有情况都是用inline函数,因为是典型的空间换时间,但是如果inline函数过多,导致所在文件过于庞大,就会被当做普通函数处理。
inline函数使用的限制

  1. inline函数一般写在头文件中。 “.h”
  2. inline函数只在realse版本下生效,debug没用。
  3. inline函数只是给编译器的一个建议。使用决定权归编译器所有。

函数默认值:

void fun(int a = 0,int b = 0,int c = 20)
{
  printf("a = %d,b = %d,c= %d\n",a,b,c,d);
}
输出 a = 0 b = 0  c = 20

  1. 在函数申明或者定义的时候,给定参数默认值,如果实参传递时,不能给该形参传值,则会按照前默认值传值
  2. 函数参数的默认值时在编译期生成指令时,直接生成入参指令
  3. 函数参数默认值只能传递常量
  4. 函数的默认值只能从右往左依次赋值
int main()
{
	fun(12);  //12<--0<--0
	fun(12, 13);//12<--13<--0
	fun(12, 13, 14); //12<--13<--14
	fun(12, , 14);//赋值是从右往左,依次赋值
}
  1. 函数中的默认值参数在作用域,只能赋值一次,不能多次赋值
  2. 因为函数参数的默认值是在编译期带入的,所以函数参数的默认值只在本文件中生效。

函数重载:
函数的原型包括函数返回类型,函数名,形参列表(其中形参名省略),且不需要函数体。

重载函数通常用来在同一个作用域内 用同一个函数名 命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处

  1. 函数名称必须相同。
  2. 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)。
  3. 函数的返回类型可以相同也可以不相同。
  4. 仅仅返回类型不同不足以成为函数的重载,在调用时会造成二义性
int Max(int a, int b);
char Max(char a, char b);
int  Max(char,char b,char c);
double Max(double a, double b);
int main()
{
    int x = Max(12,23);
    char ch = Max('a','b');
    double dx = Max(12.23,34.45);
}
void fun(int a){}
void fun(const int b){} 
//再按照 值传递,在识别函数声明相同时,并不考虑const和volatile修饰符
//调用的时候,不知道调用哪一个
//按照指针传递,
void fun(int *a){}void fun(int &a){}
void fun(const int *b){}void fun(int &a){}
int main()   //可以
{
  int a = 10;
  const int b = 20;
    fun(&a);          fun(a); //可以
    fun(&b);          fun(10);
}
//不可以重载
void fun(int a){}
void fun(int a, int b =20); //不可以 ,有二义性
//可以重载
void fun(int *p)
void fun(const int* p)
//不可以重载:
void fun(int *p)
void fun(int *const p)

**函数重载属于一种静态多态

  • 为什么C语言不能支持函数重载?
    在编译.c文件时,会将函数的参数列表去掉,只是给函数进行简单的重命名
    如:void add(int a,int b) ----> _add
    所以如果参数类型,参数个数,等构成重载的条件,都没用。调用者在调用的时候看到的只有相同的函数名
    请添加图片描述
    而.cpp文件采用了如下图的方式来对函数进行编译:因为进行了名字粉碎技术
    在编译之后 函数名就不同了
    请添加图片描述请添加图片描述
    ‘?’表示名称开始
    ‘Add’是函数名
    “@@YA” 表示参数表的开始
    “MMM” “HHH”表示返回值的类型,两个参数的类型
    “@Z”表示名称结束。

  • C++是否可以按照C风格编写 函数名前加extern “c” 即可

#include<iostream>
#include<windows.h>

extern "C" int Add(int a,int b)
{
return a+ b;
}
int main()
{
   cout<<Add(2,6)<<endl;
   system("pause");
   return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值