zoukankan      html  css  js  c++  java
  • 第二十篇 -- 研究下函数(三) —— 内联函数

    源代码编译完之后,函数就变成了一个指令的集合。调用函数时,系统将跳转到这些指令集的首地址开始运行。当函数返回时,系统就跳回到函数调用处的下一条指令继续执行。不管调用多少次,每次系统都跳转到同一地址,程序中也只有一个函数的复制。

    虽然函数节省了空间,但也不是没有代价。在调用函数的两次跳转过程中,存在一些影响性能的系统开销。如果函数本身非常短小,只有一两条指令,则跳转花费的时间就会占到较大的比重。如果可以避免跳转,则程序的执行效率就会大大提高。例如求和函数:

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

    求和在计算机中是最基本的运算,只要一条指令就可以完成。如果写成函数,则需要附加两次跳转、参数传递、函数返回等操作,这将极大地影响效率。所以,对于如此简单的功能,最好不要使用函数,而是直接计算。

    在C++中,如果在函数的声明前加上inline关键字,则称为内联函数。对于内联函数,编译器不创建真实的函数,而只是在函数调用处展开(即将函数的代码直接复制到调用处)。这样,在“调用”函数时就不用跳转了,避免了使用真实函数的代价。例如,对于add函数,如果声明为:

    inline int add(int a, int b);

    函数调用如下:

    int x = add(1, 2);

    编译后,实际的代码是:

    int x = 1 + 2;

    尽管在调用处展开内联函数,同复制函数代码是一样的,但还是使用内联函数方便,否则当需要修改代码时,就要在所有用到的地方进行修改。

    说明:如果函数是在头文件中定义的,则编译器会自动将该函数视为内联函数。不过,inline关键字和在头文件中定义函数,只是对编译器的一种建议。到底要不要将函数作为内联函数,取决于编译器的判断。有的函数是不适合作为内联函数的,如递归函数,或者有许多语句的函数。这样的函数即便是加了inline关键字,或者定义在头文件中。编译器依然会将其当做非内联的一般函数对待。

    .cpp

    #include "pch.h"
    #include <iostream>
    #include "method.h"
    using namespace std;
    
    int main()
    {
        int x = 0, y = 0;
        cout << "请输入两个整数:" << endl;
        cin >> x;
        cin >> y;
        cout << "最小值:" << min(x, y) << endl;
        return 0;
    }
    View Code

    .h

    #pragma once
    int min(int a, int b)
    {
        return a < b ? a : b;
    }
    View Code

    min函数在头文件method.h中定义,编译器自动将其识别为内联函数。并且函数非常短小,所以会在调用处展开。

  • 相关阅读:
    ASP.NET MVC 学习之路-2
    ASP.NET MVC 学习之路-1
    mvp框架
    Linq基础
    C# Lambda表达式
    三层架构基础
    Protobuf-net基础
    AutoResetEvent和ManualResetEvent
    解题报告——POJ 2299
    解题报告——POJ 2726
  • 原文地址:https://www.cnblogs.com/smart-zihan/p/11341830.html
Copyright © 2011-2022 走看看