最新公告
  • 欢迎您光临欧资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • 函数的编程风格(一)_光明网(图)

    一、内联关键字的概念

    inline 关键字是 C99 标准的类型关键字。它的作用是扩展函数并将函数的代码复制到每次调用中。这样调用函数的过程就可以直接执行函数代码,而不需要跳转、堆叠等一般的函数操作。它节省了时间,也提高了程序的执行速度。

    二、为什么需要内联函数

    在C语言中,如果某些函数被频繁调用,并且不断地把这些函数压入栈中,也就是函数栈,就会造成大量的栈空间或者栈内存的消耗。为了解决这个问题,专门引入了inline关键字,表示它是一个内联函数。堆栈空间是指函数中数据的内存空间。在一个系统下,堆栈空间的资源是有限的。如果频繁大量使用,会因为堆栈空间不足而导致错误。函数的无限循环最终会导致递归调用。结果是堆栈内存空间耗尽。

    例子:

    #include 
    //函数定义为inline即:内联函数
    inline char* dbtest(int a) {
        return (i % 2 > 0) ? "奇" : "偶";
    } 
     
    int main()
    {
       int i = 0;
       for (i=1; i < 100; i++) {
           printf("i:%d    奇偶性:%s /n", i, dbtest(i));    
       }
    }

    上面的例子是标准内联函数的使用。我们在表面上看不到使用内联修改的好处。其实内部的工作就是把每个for循环里面任何调用dbtest(i)的地方都替换成(i%2>0)?”odd”:”even”,这样就避免了重复开启的消耗通过频繁调用函数来堆栈内存。

    三、内联函数的编程风格

    1、关键字inline必须和函数的定义体放在一起才能使函数成为内联函数,仅仅在函数声明前加上inline是不行的

    例如,以下风格的函数 fun 将不是内联函数:

    inline void fun(int x, int y);  //inline仅仅与函数声明放在一起    
    void fun(int x, int y)
    {
    }

    以下风格的函数 fun 成为内联函数:

    void fun(int x, int y);
    inline void fun(int x, int y)  //inline与函数的定义放在一起
    {
    }

    2、关键字inline的使用受到限制

    内联只适用于函数体中代码比较简单的函数,不能包含复杂的结构控制语句,如while、switch,内联函数本身不能是直接递归函数(函数内部调用自己的函数)。

    3. inline 只是对编译器的建议

    内联函数只是给编译器的一个建议,所以到底能不能真正内联还要看编译器的意思。如果它认为函数不复杂,可以在调用点展开,就会内联,而不是声明内联函数。Inline 会内联,声明 inline 只是一个建议。

    4. 建议:内联函数的定义放在头文件中

    其次,由于内联函数是在调用处展开的,编译器必须到处都能看到内联函数的定义,否则就变成了对非内联函数的调用。因此,这要求内联函数的定义出现在每个调用内联函数的文件中。

    因此,在头文件中实现内联函数定义是合适的,省去了为每个文件实现一次的麻烦。

    声明要与定义一致:如果内联函数在每个文件中实现一次小程序关键词怎么设置,那么最好保证每个定义都相同,否则会导致未定义的行为。如果每个文件中的定义不一样,那么编译器扩展哪一个取决于具体的编译器。因此,最好将内联函数定义放在头文件中。

    5. 谨慎使用内联

    内联可以提高函数的执行效率,为什么不把所有的函数都定义为内联函数呢?如果所有函数都是内联的,是否还需要使用关键字“内联”?

    内联是以代码膨胀(复制)为代价的,只是节省了函数调用的开销,从而提高了函数的执行效率。如果在函数体中执行代码的时间与函数调用的开销相比很大,那么效率增益就会很小。另一方面,每个内联函数调用都必须复制代码,这会增加程序的总代码大小并消耗更多的内存空间。

    内联不应该用于以下情况:

    (1)如果函数体中的代码很长,使用内联会导致更高的内存消耗成本。

    (2)如果函数体中有循环,函数体中代码的执行时间大于函数调用的代价。一个类的构造函数和析构函数很容易被误解为使用内联效率更高。当心构造函数和析构函数可能会隐藏一些行为,比如“偷偷”执行基类或成员对象的构造函数和析构函数。所以不要随便把构造函数和析构函数的定义体放在类声明中. 一个好的编译器会根据函数定义的主体自动删除不值得的内联(这进一步表明内联不应该出现在函数声明中)。

    6、结合使用静态和内联

    static 是一个静态修饰符。其关键字修改的变量将被保存到全局数据区。对于普通的局部变量或全局变量,系统会在变量离开作用域时自动分配内存并释放。使用static关键字进行修改,只会在程序结束时释放。使用静态内联修改时,函数只在文件内部可见,不会污染命名空间。另外,函数在运行过程中也会分配内存空间,但是由于静态的存在,就像修改过的变量一样,只会开辟一块内存空间。

    6、内联函数有点像带参数的宏

    内联函数虽然类似于带参数的宏,但在用法上却与宏有很大不同:

    内联函数和带参数的宏的区别

    内联()函数

    带参数的宏

    时间扩展

    在编译时展开,因此 inline 关键字是编译关键字

    在预处理期间展开小程序关键词怎么设置,因此#define 关键字是预处理关键字

    参数类型检查

    inline() 函数是一个执行严格参数类型检查的函数

    不检查参数类型,只是做简单的字符串替换,所以在使用带参数的宏时会有一些副作用,编程是为了人为防止

    是否允许复杂语句

    不允许使用复杂语句,如果出现复杂语句,例如递归、大循环等,函数将不会展开。

    对此没有要求。宏只是在不理解语句含义的情况下进行字符串替换

    必须扩大

    不一定,是否扩展由编译器决定

    是的,只要使用宏,就可以保证扩展

    inline 和#define 的区别:

    内联由编译器一起处理,之后的函数体直接插入到调用的地方。

    #defines 由预处理器处理,只需简单的文本替换,无需任何编译过程。

    站内大部分资源收集于网络,若侵犯了您的合法权益,请联系我们删除!
    欧资源网 » 函数的编程风格(一)_光明网(图)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    欧资源网
    一个高级程序员模板开发平台

    发表评论