152-C++基础(形参带默认值的函数,inline内联函数)

1、形参带默认值的函数

  • 1、给默认值的时候,只能从右向左给!!!
  • 2、调用效率的问题(少了一句move的调用
  • 3、函数定义处可以给形参默认值,函数声明处也可以给形参默认值
  • 4、形参给默认值的时候,不管是函数定义处给,还是函数声明处给每一个形参的默认值只能出现一次!!!哪怕值一样也不可以!!!
  • 函数的声明可以无数次,但是定义只能一次

在这里插入图片描述
上面这样写是错误的,因为编译器从上到下编译,形参默认值是从右向左给
在这里插入图片描述
上面这样可行。因为编译器从上到下编译代码,默认从右向左的顺序看,b=20,a=10

在这里插入图片描述
在这里插入图片描述

  • 如果只传入参数a,则b就是使用默认值20
  • 如果给a和b都添加默认值,那么在调用的时候就可以不用传参数了。

注意:

  • 我们给参数是从左向右给,实际上压栈是从右向左压,所以给默认值的时候必须是从右向左给!!!

下面这种写法是错误的!!!在这里插入图片描述

调用效率的问题:

  • 带形参的默认值函数效率增高!少了1句move指令
#include <iostream>
using namespace std;



//sum(, 20);这个写法是错误的

int sum(int a, int b = 20);
int sum(int a = 10, int b);
int main()
{
	int a = 10;
	int b = 20;

	int ret = sum(a, b);
	/*
	mov eax, dword ptr[ebp-8]
	push eax 入栈

	mov ecx, dword ptr[ebp-4]
	push ecx
	call sum
	*/
	cout << "ret:" << ret << endl;


	/*
	push 14H
	mov ecx, dword ptr[ebp-4]
	push ecx
	call sum
	*/
	ret = sum(a);


	/*
	push 14H
	push 0Ah
	call sum
	*/
	ret = sum();//和sum(20, 50);是一样的


	ret = sum(a, 40);
	/*
	push 28H
	mov ecx, dword ptr[ebp-4]
	push ecx
	call sum 这个和ret = sum(a);一样
	*/

	return 0;
}

int sum(int a, int b)
{
	return a + b;
}

2、inline内联函数

面试问题:inline内联函数 和 普通函数的区别???

  • 普通函数调用有标准的开销,介绍下函数的开销,我前面文章有讲过;
  • 内联函数在函数的调用点直接把函数的代码进行展开处理了,没有函数的调用开销了;
  • 如果函数在短时间内大量调用,可以将函数设置成内联函数

一个函数调用时,标准的函数调用过程:

  • 从右向左压实参,压完实参后,执行call指令,将call指令的下一行地址入栈;
  • 进入被调用函数中,sum的{,执行push ebp,将调用方main函数的地址入栈;然后给sum函数开辟栈帧,给sum函数栈帧初始化(linux下gcc和g++只负责开辟栈帧,不对帧的内存初始化)

  • 以上也叫做 函数调用过程中的开销(实参压栈、栈帧开辟、栈帧回退)

其实sum函数只有x+y,是非常简单的,只有mov,add,move这几个指令,但是实际上确需要有函数调用开销,一次不多,如果千万次调用,就开销很大了。

inline内联函数:

  • 在编译过程中,就没有函数的调用开销了,在函数的调用点直接把函数的代码进行展开处理了!!!

在这里插入图片描述

  • inline函数在符号表中不再生成相应的函数符号!!!因为在函数调用点直接展开了!!!
  • 但是不是所有的inline都会被编译器处理成内联函数 - 比如说递归;因为编译器是不执行代码的指令的,所以就不知道递归调用自己多少次。
  • 而且如果这个函数代码量巨大,即使你写内联,编译器也不会内联处理,而且名字可能冲突了。
  • 所以inline只是建议编译器把这个函数处理成内联函数!!!(是否inline成功,由编译器决定)

注意:

  • 在debug版本上,inline是不起作用的,因为需要调试;inline只有在release版本下才能出现

反汇编代码:(表示vs2019上调试)
在这里插入图片描述
在Linux下查看是否内联函数:

  • 在Linux下执行 g++ -c main.cpp -O2 (-c直接生成.o文件,不生成可执行文件)
    objdump -t main.o(查看符号表 判断是否内联了,因为内联函数是没有符号的)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liufeng2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值