首页 > 编程语言 >C++内联函数

C++内联函数

时间:2024-04-26 11:44:17浏览次数:23  
标签:函数 int sp C++ ax inline 内联

内联函数

关键字inline,inline是空间换时间,提高了程序效率但花费了更多空间。举个例子,下面是一段C语言代码:

void fun(int i)
{
    return i*2;
}

int main()
{
    int a = 4;
    int b = fun(a);
}

假定以上C文件被编译器编译成的汇编代码如下:

_f_int:
	add ax,@sp[-8]	;相当于ax = ax + 4
	ret
_main:
	add sp,#8	;堆栈指针SP移动8个字节,空出来的8个字节分别存放a,b
	mov ax,#4	;将立即数4送往寄存器ax中
	mov @sp[-8],ax	;将ax的值送往堆栈指针-8个字节的内存单元中,可以看做a = 4这一操作
	mov ax,@sp[-8]	;将a的值赋值给ax
	push ax		;将寄存器的内容压入栈中
	call _f_int	;call会做两件事,先把下一条指令的地址压入栈中,再跳转到要执行的子程序
	mov @sp[-4],ax	;将ax的值赋值给b
	pop ax		;将函数中的临时变量i出栈

函数调用需要做如下事情:将函数参数压入栈中、将返回地址压入栈中、准备返回值、将所有以上入栈的内容出栈。为了提高效率,设置关键字inline告诉编译器这个一个声明而非定义,在调用这个被inline修饰的函数时会将代码直接嵌入到调用的地方。有点类似于宏定义,宏定义是在编译前对所有的内容进行替换不涉及类型检查,而内涵函数存在类型检查。内联函数经过编译不会生成obj文件

通过加了inline关键字的函数编译后结果:
image
可以看到汇编代码不会执行部分入栈和出栈操作,从而提高了程序的效率。
普通函数与内联函数:
普通函数时通过跳转到函数体里面执行程序,会有一些入栈出栈等操作;内联函数就是将代码嵌入调用该函数的位置,每调用一次就嵌入一次,因此提高了程序执行效率但增大了内存空间,所以说是空间换时间的策略
image


通常在程序设计时要求.h文件存放函数声明,.cpp文件对函数进行定义。

//a.h
inline void f(int i, int j);

//a.cpp
#include "a.h"
void f(int i, int j)
{
	cout << i << "," << j << endl;
}

//main.cpp
int main()
{
	f(10,10);
	return 0;
}

执行以上代码会出错:
image

解决方法:不需要a.cpp文件,将f内联函数的定义放在头文件中。

<br>
//a.h
#include <iostream>
using namespace std;
inline void f(int i, int j)
{
    cout << i << "," << j << endl;
}

//main.cpp
#include "a.h"
int main()
{
    f(10,10);
    return 0;
}

结果:
image

总结:

1.内联函数采取的是空间换时间的策略。
2.通常函数代码只有2~3行或者是被重复调用的函数,可以添加inline关键字。
3.某些情况即使添加了inline,如果程序占用空间过大,编译器也不会将该函数看做是内联函数

参考:
浙江大学翁凯C++
C++ Primer Plus 第8章

标签:函数,int,sp,C++,ax,inline,内联
From: https://www.cnblogs.com/qianxiaohan/p/18159637

相关文章

  • 类成员函数作为回调使用示例
    在编写C++项目时,经常需要将类的某个成员函数作为回调函数使用,这里总结两个方法:1.使用lambda函数,将类函数封装后使用,代码示例:#include<funtional>#include<memory>classA{public:A(std::function<int(int)>callback):m_callback(callback){}intRun(......
  • 【Qt 专栏】QString::arg()函数
    原文链接:https://blog.csdn.net/Gnar_w/article/details/134966919作者:Gnar_w  (CSDN) 一、说明在QT的QString中,arg方法类似于C中的printf中使用的格式输出符(仅有些许类似)。二、使用有以下方式:使用arg(str1,str2,str3)这种方法进行替换。使用arg(str1).arg(str2).arg(......
  • C#中常用作event的delegate 函数
    1publicdelegatevoidEventHandler<TEventArgs>(objectsender,TEventArgse);使用例子:publiceventEventHandler<TcpClientKickedEventArgs>ClientKicked;//怎样调用if(ClientKicked!=null){ClientKicked(this,newTcpClientKickedE......
  • dotnet C# 使用 Win32 函数获取用户下载文件夹的路径的方法
    大家都知道,在dotnet里面的可以使用Environment.GetFolderPath方法配合Environment.SpecialFolder枚举列出当前运行环境下的一些特殊文件夹。然而SpecialFolder枚举不包含对Download下载文件夹的枚举值,如咱需要获取用户当前的下载文件夹,需要使用Win32方法来辅助获取在......
  • 编码技巧C++
    编码技巧C++非零都是true在c++环境下不等于0的数值都被认为是true在判断一个值是否为0时以下代码是等效的,但第一种效率更高inti=123;if(i)cout<<"i不为0";if(i!=0)cout<<"i不为0";不需要用到下标的计数循环可以不用for语句intn;cin>>n;while(n--){......
  • 双向循环链表的插入处理函数接口
    //方便访问,创建一个带头结点的双向循环链表//链表数据域取别名方便修改typedefintDataType_t;//构造双向循环链表的结点typedefstructDoubleCircularLList{DataType_tdata;//数据域structDoublLingkedList*prev;//直接前驱指针域......
  • C++ 多级继承与多重继承:代码组织与灵活性的平衡
    C++多级继承多级继承是一种面向对象编程(OOP)特性,允许一个类从多个基类继承属性和方法。它使代码更易于组织和维护,并促进代码重用。多级继承的语法在C++中,使用:符号来指定继承关系。多级继承的语法如下:classDerivedClass:publicBaseClass1,publicBaseClass2,...{......
  • vue中函数使用、class和style属性、条件渲染、列表渲染、数据的双向绑定、input事件、
    【事件指令中的函数使用】1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8">5<title>Title</title>6<scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&......
  • 设计带内存分配的C++类需要注意的几点
    初级内存管理:需要在构造函数中分配内存给ptr,并在析构函数中释放内存,以避免内存泄漏。MyClass::MyClass(){ptr=newint;}MyClass::~MyClass(){deleteptr;}深拷贝:如果您需要实现复制构造函数和赋值运算符重载,您需要进行深拷贝,以确保复制后的对象拥有独......
  • 生成函数
    生成函数我们可以把生成函数看作是代数对象,其形式上的处理使得人们可以通过代数手段计算一个计数问题。通常我们默认级数是收敛的。(主要原因在于代数手段往往是需要保证收敛的)本文章不涉及多项式题目(交给考拉)普通生成函数的定义为:\[\displaystyle\sum_{n}a_nx^n\]常见的......