zoukankan      html  css  js  c++  java
  • 宏定义与内联函数

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

    宏定义示例1:MAX宏,求2个数中较大的一个
    #define MAX(a, b) (((a)>(b)) ? (a) : (b))
    关键:
    第一点:要想到使用三目运算符来完成。
    第二点:注意括号的使用

    宏定义示例2:SEC_PER_YEAR,用宏定义表示一年中有多少秒
    #define SEC_PER_YEAR (365*24*60*60UL)
    关键:
    第一点:当一个数字直接出现在程序中时,它的是类型默认是int
    第二点:一年有多少秒,这个数字刚好超过了int类型存储的范围

    带参宏和带参函数的区别(宏定义的缺陷)
      (1)宏定义是在预处理期间处理的,而函数是在编译期间处理的。这个区别带来的实质差异是:宏定义最终是在调用宏的地方把宏体原地展开,而函数是在调用函数处跳转到函数中去执行,执行完后再跳转回来。
    注:宏定义和函数的最大差别就是:宏定义是原地展开,因此没有调用开销;而函数是跳转执行再返回,因此函数有比较大的调用开销。所以宏定义和函数相比,优势就是没有调用开销,没有传参开销,所以当函数体很短(尤其是只有一句话时)可以用宏定义来替代,这样效率高。
      (2)带参宏和带参函数的一个重要差别就是:宏定义不会检查参数的类型,返回值也不会附带类型;而函数有明确的参数类型和返回值类型。当我们调用函数时编译器会帮我们做参数的静态类型检查,如果编译器发现我们实际传参和参数声明不同时会报警告或错误。
    注:用函数的时候程序员不太用操心类型不匹配因为编译器会检查,如果不匹配编译器会叫;用宏的时候程序员必须很注意实际传参和宏所希望的参数类型一致,否则可能编译不报错但是运行有误。
      总结:宏和函数各有千秋,各有优劣。总的来说,如果代码比较多用函数适合而且不影响效率;但是对于那些只有一两句话的函数开销就太大了,适合用带参宏。但是用带参宏又有缺点:不检查参数类型。

      

    2、内联函数和inline关键字
    (1)内联函数通过在函数定义前加inline关键字实现。
    (2)内联函数本质上是函数,所以有函数的优点(内联函数是编译器负责处理的,编译器可以帮我们做参数的静态类型检查);但是他同时也有带参宏的优点(不用调用开销,而是原地展开)。所以几乎可以这样认为:内联函数就是带了参数静态类型检查的宏。
    (3)当我们的函数内函数体很短(譬如只有一两句话)的时候,我们又希望利用编译器的参数类型检查来排错,我还希望没有调用开销时,最适合使用内联函数。

  • 相关阅读:
    C#中对ActiveX控件的调用
    C#打开播放器后指定其播放的视频文件的路径代码怎么写啊!
    利用Visual C#开发一个媒体播放器
    C# 播放器控件 的常用方法
    用C#打开一个pdf文件
    C#利用微软DirectX做的视频播放器
    请问C#高手: [DllImport("kernel32.dll")]是什么意思??
    C#中的abstract与virtual
    ListBox Grouping的研究(一):初探GroupItem对象
    一个“>”导致我调试了1个小时才解决问题
  • 原文地址:https://www.cnblogs.com/PengfeiSong/p/6263057.html
Copyright © 2011-2022 走看看