内联函数(五)

或许我们在 C 语言中听说过内联函数,但是内联函数是首先在 C++ 中提出来的,可能现代的 C 编译器支持内联函数。

C++ 中的 const 常量可以代替宏常数定义,如:const int A = 3; <==> #define A 3;那么在 C++ 中是否有解决方案代替宏代码片段呢?在 C++ 中推荐使用内联函数替代宏代码片段,使用 inline 关键字声明内联函数。内联函数声明时 inline 关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。

C++ 编译器可以将一个函数进行内联编译,被 C++ 编译器内联编译的函数叫做内联函数;C++ 编译器直接将函数插入函数调用的地方,内联函数没有普通函数调用时的额外开销(压栈,跳转,返回等);但 C++ 编译器不一定会满足函数的内联请求!

我们以代码为例来进行分析

#include <stdio.h>

#define FUNC(a, b) ((a) < (b) ? (a) : (b))

inline int func(int a, int b)
{
    return a < b ? a : b;
}

int main(int argc, char *argv[])
{
    int a = 1;
    int b = 3;
    int c = FUNC(++a, b);
    
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    printf("c = %d\n", c);
    
    return 0;
}

我们在第 3 行定义了宏函数,返回两个数中的较小值;在第 5 行定义函数返回较小值。我们先用宏函数来返回,在第 14 行比较 ++a 和 b 的值,明显返回的是 2,那么最后的值就为 a = 2, b = 3, c = 2;我们来看看结果

我们看到的是返回的是 3,仔细看下程序,我们调用的是宏函数,也就是说,这个 ++a 被执行了两次,所以返回 3 很正常。我们再来把宏函数调用换成函数调用,看看结果

我们看到这次和我们分析的是一致的啦,那么宏函数和函数还是有区别的,宏函数有弊端。

下来我们来讲讲内联函数,内联函数具有普通函数的特征(参数检查,返回类型等);函数的内联请求可能会被编译器拒绝;函数被内联编译后,函数体直接扩展到调用的地方;宏代码片段由预处理器处理,进行简单的文本替换,没有任何的编译过程,因此可能出现副作用。

现代 C++ 编译器能够进行编译优化,一些函数即使没有 inline 声明,也可能被内联编译;一些现代的 C++ 编译器通过了扩展语法,能够对函数进行强制内联,如:g++:__attribute__((always_inline))属性; MSVC:__forcrinline

下来我们以代码为例进行分析

#include <stdio.h>

inline 
int add_inline(int n);

int main(int argc, char *argv[])
{
    int r = add_inline(10);

    printf(" r = %d\n", r);

    return 0;
}

inline int add_inline(int n)
{
    int ret = 0;

    for(int i=0; i<n; i++)
    {
        ret += i;
    }

    return ret;
}

我们在 VS2010 中通过断点调试进到反汇编,看看内联函数生效了没。在第 8 行通过调用内联函数 add_inline,我们看到汇编函数如下

我们看到有 call 的调用,证明内联请求失败了。还是调用了函数,并没有在这块直接把函数体铺开。这也证明了我们之前所说的不是每一个内联请求都会得到执行。

在 C++ 中 inline 内联编译有这么几种条件限制:a> 不能存在任何形式的循环语句;b> 不能存在过多的条件判断语句;c> 函数体不能过于庞大;d> 不能对函数进行取址操作;e> 函数内联声明必须在函数调用语句之前;

通过对内联函数的学习,总结如下:1、C++ 中可以通过 inline 声明内联函数;2、编译器直接将内联函数体扩展到函数调用的地方;3、inline 只是一种请求,编译器不一定允许这种请求;4、内联函数省去了函数调用时压栈、跳转和返回的开销。

欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。

原文地址:http://blog.51cto.com/12810168/2113184

时间: 2024-10-13 16:05:15

内联函数(五)的相关文章

内联函数详解

什么是内联性和外联函数 类的成员函数可以分为内联函数和外联函数.内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内.而说明在类体内,定义在类体外的成员函数叫外联函数.外联函数的函数体在类的实现部分. 内联函数在调用时不是像一般的函数那样要转去执行被调用函数的函数体,执行完成后再转回调用函数中,执行其后语句,而是在调用函数处用内联函数体的代码来替换,这样将会节省调用开销,提高运行速度. 内联函数与前面讲过的带参数的宏定义进行一下比较,它们的代码效率是一样的,但是内联函数要优于宏定义

位运算+引用+const+new/delete+内联函数、函数重载、函数缺省参数

一.位运算 应用: 1.判断某一位是否为1 2.只改变其中某一位,而保持其它位都不变 位运算操作: 1.& 按位与(双目): 将某变量中的某些位清0(与0位与)且同时保留其它位不变(与1位与):获取某变量中某一位(与其位与后判断是否为该数) 2.|  按位或(双目): 将某变量中的某些位置1(与1位或)且保留其它位不变 3.^  按位异或(双目): 将某变量中的某些位取反(与1异或)且保留其它位不变 异或运算特点: 如果 a^b=c,那么就有 c^b = a以及c^a=b.(穷举法可证---用于

函数新特性、内联函数、const详解

一.函数回顾与后置返回类型 函数定义中,形参如果在函数体内用不到的话,则可以不给形参变量名字,只给其类型. 函数声明时,可以只有形参类型,没有形参名 把函数返回类型放到函数名字之前,这种写法,叫前置返回类型. C++11中,后置返回类型,在函数声明和定义中,把返回值类型放到参数列表之后. 前面放auto,表示函数返回类型放到参数列表之后,而放在参数列表之后的返回类型是通过 -> 开始的. 1 #include <iostream> 2 using namespace std; 3 4 v

关于C++内联函数

关于C++内联函数有以下实验: 有三段测试代码 1.手动展开内联函数. 2.非内联函数. 3.inline标记的内联函数.(函数只有一行代码,以确保函数被内联) 测试三种情况: VS工程在Release版下的有关内联的三个设置选项 1./Ob0 禁用内联展开(默认情况下是打开的). 2./Ob1 只展开标记为 inline 或 __inline 的函数,或在类声明内定义的 C++ 成员函数中的函数. 3./Ob2 展开标记为 inline 或 __inline 的函数和编译器选择的任何其他函数(

java内联函数

在说内联函数之前,先说说函数的调用过程. 调用某个函数实际上将程序执行顺序转移到该函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到  转去执行该函数前的地方.这种转移操作要求在转去前要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保  存地址继续执行.也就是通常说的压栈和出栈.因此,函数调用要有一定的时间和空间方面的开销.那么对于那些函数体  代码不是很大,又频繁调用的函数来说,这个时间和空间的消耗会很大. 那怎么解决这个性能消耗问题呢,这个时候需要引入内联函数了.内联函数

内联函数的定义及说明

一.什么叫inline函数? inline(小心,不是online),翻译成"内联"或"内嵌".意指:当编译器发现某段代码在调用一个内联函数时,它不是去调用该函数,而是将该函数的代码,整段插入到当前位置.这样做的好处是省去了调用的过程,加快程序运行速度.(函数的调用过程,由于有前面所说的参数入栈等操作,所以总要多占用一些时间).这样做的不好处:由于每当代码调用到内联函数,就需要在调用处直接插入一段该函数的代码,所以程序的体积将增大.拿生活现象比喻,就像电视坏了,通过

宏定义与内联函数

1.宏定义的规则和使用解析(1)宏定义的解析规则就是:在预处理阶段由预处理器进行替换,这个替换是原封不动的替换.(2)宏定义替换会递归进行,直到替换出来的值本身不再是一个宏为止.(3)一个正确的宏定义式子本身分为3部分:第一部分是#dedine ,第二部分是宏名 ,剩下的所有为第三部分.(4)宏可以带参数,称为带参宏.带参宏的使用和带参函数非常像,但是使用上有一些差异.在定义带参宏时,每一个参数在宏体中引用时都必须加括号,最后整体再加括号,括号缺一不可. 宏定义示例1:MAX宏,求2个数中较大的

C++内联函数总结

C++内联函数 Inline函数,看起来像函数,动作像函数,没有宏的副作用,可以调用它们又没有函数调用的额外开销.多好的内联函数 实际上,获得的比想象的还要多,避免函数调用的额外开销只是它好处的一部分而已.编译器还可以通过最优化机制(被设计用来浓缩那些'不含函数调用的代码'的代码),所以当inline某个函数,编译器可能就有能力对它执行语境相关最优化. 但是函数调用会增加目标代码的大小,然而,如果inline函数的本体很小,编译器针对'函数本体'产出的代码可能比'函数调用'产生的目标代码更小.

谈谈 OC 中的内联函数

内联函数 即在编译的时候将函数体替换函数调用,从而不需要将parameter,returnaddress进行push/pop stack的操作, 从而加速app的运行,然而,会增加二进制文件的大小. 疑问:内联函数和非内联函数有很大不同吗? 解答:对硬件硬性不大,但在性能上有影响. 内联函数不能保证编译时候一定是内联的,内联仅仅是告诉编译器请求内联,但编译器不一定内联. 内联函数的使用场景: OC--->结构体CGRectMake--->在快速赋值的时候就是调用了其内联函数 CG_INLINE