鱼C论坛

 找回密码
 立即注册
查看: 2540|回复: 0

[学习笔记] 026-C++之函数重载、内联函数、默认参数、占位参数

[复制链接]
发表于 2018-8-28 16:49:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 moc 于 2018-8-28 16:49 编辑

1、函数重载
1.定义
        可以在同一作用域内用同一个函数名来定义不同的函数,当函数名和不同的参数搭配时函数的含义不同。

  1. int Add(int a, int b)
  2. {
  3.         return a + b;
  4. }
  5. int Add(int a, int b, int c)
  6. {
  7.         return a + b + c;
  8. }

  9. double Add(int a, double b)
  10. {
  11.         return double(a) + b;
  12. }
  13. double Add(double a, int b)
  14. {
  15.         return a + double(b);
  16. }
  17.         double a = 10;
  18.         cout << Add(12, 21) << endl;   
  19.         cout << Add(12, 23, 45) << endl;

  20.         cout << Add(a, 20) << endl;
  21.         cout << Add(20, a) << endl;
复制代码

2.函数重载规则
函数重载至少满足下面一个条件:
        ①函数参数个数不同
        ②函数参数类型不同
        ③函数参数顺序不同

注意事项:
        仅仅返回类型不同不足以成为函数的重载,函数重载是由函数名和参数列表决定的。
函数重载的作用:
        重载函数通常用来在同一个作用域内 用同一个函数名 命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。
函数重载的本质:
1.C语言中为什么不能支持函数重载?
        360截图20180828154116503.jpg
        C编译器在编译.c文件时,只会给函数进行简单的重命名;具体的方法是给函数名之前加上”_”;所以加入两个函数名相同的函数在编译之后的函数名也照样相同;调用时就会因为不知道到底调用那个而出错.
2.C++对函数重载的底层处理
        360截图20180828154147864.jpg
        在.cpp文件中,虽然两个函数的函数名一样,但是他们在符号表中生成的名称不一样,‘?’表示名称开始,‘?’后边是函数名“@@YA”表示参数表开始,后边的3个字符分别表示返回值类型,两个参数类型。“@Z”表示名称结束。 正是由于在.cpp文件中,两个函数生成的符号表中的名称不一样,所以是可以编译通过的。
3.C++中按照C的风格来编译一个函数
  1. extern "C" int Add(int a, int b)
  2. {
  3.         return a + b;
  4. }
复制代码

C++中,只需在函数名前加extern "C" 就可以完成按照C风格来编译。

2、内联函数
        常规函数执行时,程序将在函数调用后立即存储函数的返回内存地址,并将函数参数复制到堆栈(为此保留的内存块),跳到标记函数起点的内存单元,执行函数代码(也许还需将返回值放入寄存器中),然后跳回到地址被保存的指令处(这与阅读文章时停下来看脚注,并在阅读完脚注后返回到以前阅读的地方类似)。来回跳跃并记录跳跃位置意味着使用函数时,需要一定的额外开销。
        内联函数提供了另一种选,在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。从而节省调用函数时的开销。
        如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。

说明1:内联函数的声明和实现需要写在一块,被C++内联编译的函数叫做内联函数。
说明2:内联函数在最终生成的函数中是没有定义的,C++直接将函数体插入到调用的地方。
说明3:C++编译器不一定会准许函数的内联请求,(inline关键字只是向编译器请求内联编译)。
说明4:内联函数由编译器处理,直接将编译好的函数体插入到调用的地方。
           宏代码片段由预处理器处理,进行简单的文本替换,没有任何编译的过程。
说明5:现代的C++编译器进行了编译优化,一些函数即使没有inline声明,也可能被编译成内联函数。
说明6:一些C++编译器提供了扩展语法,可以对函数进行强制的内联编译。
           如:g++ 的__attribute__((always_inline))属性。

3、默认参数
C++中在函数声明时为参数提供一个默认值,当函数调用时如果没有指定这个参数的值,编译器会自动使用默认值来代替。
  1. void myprintf(int x, int y = 4, int z = 5)
  2. {
  3.         cout << x << y << z;
  4. }

  5. int main()
  6. {
  7.         myprintf(3);
  8.         myprintf(3, 5);
  9.         myprintf(3, 5, 7);
  10.         system("pause");
  11.         return 0;
  12. }
复制代码

使用规则:
        一旦在一个函数声明中开始使用默认参数,其后面的参数都必须使用默认参数。

4、占位参数
c++在声明函数时,可以设置占位参数。占位参数只有参数类型声明,而没有参数名声明。

  1. //函数占位参数,函数调用时,必须写够参数
  2. int func(int a, int b, int)
  3. {
  4.         return a + b;
  5. }
复制代码

这个占位参数的用法应该是用于在函数的声明和实现分离的时候,在函数声明的时候可以只写参数类型不写变量名,在定义(实现)的时候在加上变量名。

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-22 03:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表