http://hi.baidu.com/pobenliu/blog/item/3e458208279486a32fddd43f.html

宏、函数、宏函数的区别

先说宏和函数的区别:

1. 宏做的是简单的字符串替换(注意是字符串的替换,不是其他类型参数的替换),而函数的参数的传递,参数是有数据类型的,可以是各种各样的类型.
2. 宏的参数替换是不经计算而直接处理的,而函数调用是将实参的值传递给形参,既然说是值,自然是计算得来的.
3. 宏在编译之前进行,即先用宏体替换宏名,然后再编译的,而函数显然是编译之后,在执行时,才调用的.因此,宏占用的是编译的时间,而函数占用的是执行时的时间.
4. 宏的参数是不占内存空间的,因为只是做字符串的替换,而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的.
5. 函数的调用是需要付出一定的时空开销的,因为系统在调用函数时,要保留现场,然后转入被调用函数去执行,调用完,再返回主调函数,此时再恢复现场,

这些操作,显然在宏中是没有的.

现在来看内联函数:

所谓"内联函数"就是将很简单的函数"内嵌"到调用他的程序代码中,只样做的目的是为了避免上面说到的第5点,目的旨在节约下原本函数调用时的时空开销.但必须注意的是:作为内联函数,函数体必须十分简单,不能含有循环、条件、选择等复杂的结构,否则就不能做为内联函数了。事实上,即便你没有指定函数为内联函数,有的编译系统也会自动将很简单的函数作为内联函数处理;而对于复杂的函数,即便你指定他为内联函数,系统也不会理会的。

函数和宏函数的区别就在于,宏函数占用了大量的空间,而函数占用了时间。大家要知道的是,函数调用是要使用系统的栈来保存数据的,如果编译器里有栈检查选项,一般在函数的头会嵌入一些汇编语句对当前栈进行检查;同时,CPU也要在函数调用时保存和恢复当前的现场,进行压栈和弹栈操作,所以,函数调用需要一些CPU时间。

而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序,不会产生函数调用,所以仅仅是占用了空间,在频繁调用同一个宏函数的时候,该现象尤其突出。

1. 宏在编译之前进行,即先用宏体替换宏名,然后再编译的,而函数显然是编译之后,在执行时,才调用的.因此,宏占用的是编译的时间,而函数占用的是执行时的时间.
这句分开解释:
"" 宏在编译之前进行,即先用宏体替换宏名,然后再编译的,""
解释:假设代码中有这么一条宏定义:#define MAX_LEN 10(10是宏体, MAX_LEN 是宏名)则在编译之前, 也就是在预编译的时候会将代码中所有出现MAX_LEN的地方替换成10后在进行下面的代码编译, 这种替换工作实在编译之前进行的...
"" 而函数显然是编译之后,在执行时,才调用的""
解释: 函数调用实在执行时才调用的这是显然的, 因为只有执行时才能根据具体的条件决定调用哪个函数""因此,宏占用的是编译的时间,而函数占用的是执行时的时间. ""
解释:有了上面的解释,估计这句话也就知道了, 从他的这句话看书的作者把预编译也算作编译的一部分了...
2.宏的参数是不占内存空间的,因为只是做字符串的替换,而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的.
同样分开解释:"" 宏的参数是不占内存空间的,因为只是做字符串的替换""
解释:假设有这么个宏定义#define MAX(a, b) (a) > (b) ? (a) : (b) 代码中所有出现(初定义外)MAX(a, b)的地方在预编译以后都变成了 (a) > (b) ? (a) : (b)这个式子, 比如代码中有c = MAX(1, 3)这样的语句, 则在预编译的时候就会变成c = (1) > (3) ? (1) : (3), 这是一种直接的替换, 不会产生中间变量, 所以也就不用为之分配空间 ..."而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的."
解释: 函数调用时需要为每个形式参数在栈上分配空间, 然后将实参的值拷贝进去, 在函数的内部用的都是这个形参, 当函数结束后形参的空间会被自动释放掉, 这也是为什么形参的改变无法改变实参的值的原因...
================================================== 宏:                                                  内联函数: 1.由预处理器处理                             1.编译器处理 2.对++/--操作有副作用                      2.可能会被编译器拒绝(不一定内联) 3.难于调试                                        3.可能造成代码膨胀 4.必定被展开
**************************************************************************************************************************************
宏函数和函数的使用小结:
函数体量很小时,为了减小系统的开销时间,可以使用宏函数,而函数体比较复杂(需要递归、循环、判断、选择等...)的
情况下,使用函数来定义可以避免宏函数定义带来的副作用。  宏函数是在程序编译时进行简单的字符替换,而函数是在程序生成后才进行调用,这时会占用开销时间(主程序函数保留现场,在子函数体中需要进行参数的传递--实参传递给形参以及调用完后形参的销毁等步骤 ),因此宏函数占用的编译时的时间,而函数占用的是执行时的时间。  因此在函数体量简单的情况下,使用宏函数可以
极大的提高程序的执行效率和系统开销。

宏、函数、宏函数的区别相关推荐

  1. C语言【宏定义与函数的区别】

    在代码开发过程中,有一些常用或者可以通用的功能或者代码段,实现这些功能,既可以写成函数,也可以封装成为宏定义.那么究竟是用函数好,还是宏定义好?这就要求我们对二者进行合理的取舍. 先看宏 宏: #de ...

  2. C语言中宏定义和函数的区别

    前言 在C语言中,对于一些常用或通用的代码段的封装可以有两种方式:函数和宏定义. 这篇博客就来带大家梳理一下对于这两种方式我们在使用时应该如何抉择,以及它们的区别和优缺点. 宏定义和函数的区别 从程序 ...

  3. 宏函数和函数的区别及其优缺点

    宏定义,编译预处理指令,在编译预处理时即进行简单的字符替换,也只进行简单的字符替换.而宏定义的函数和用户定义的函数在使用时有什么区别?如下: 1.宏函数会在编译预处理时展开,只占编译时间,函数调用则会 ...

  4. 宏定义与预处理、函数和函数库

    以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除. 一.C语言预处理理论 1.由源码到可执行程序的过程 源码.c->(编译)->elf可执行程序 源码.c->(编译)-> ...

  5. 6、宏定义与预处理、函数与函数库

    C语言预处理理论 由源码到可执行程序的过程 源码.c->(编译)->elf可执行程序 源码.c->(编译)->目标文件.o->(链接)->elf可执行程序 源码.c ...

  6. c++用宏定义和函数来求圆的面积,半径可为表达式

    本题是输入整数或表达式进入宏定义和函数来求面积的.若将输入的半径改成表达式则会因为宏定义与函数的不同,有所区别. 因为宏定义是直接替换,所以例如输入为确定的值时,宏定义和函数的编写可以没有区别,例如下 ...

  7. 秀操作:函数宏的三种封装方式

    关注.星标公众号,直达精彩内容 1. 函数宏介绍 函数宏,即包含多条语句的宏定义,其通常为某一被频繁调用的功能的语句封装,且不想通过函数方式封装来降低额外的弹栈压栈开销. 函数宏本质上为宏,可以直接进 ...

  8. 秀操作 | 函数宏的三种封装方式

    作者:☆星轨★ 链接:https://blog.csdn.net/qq_35692077/article/details/102994959 1. 函数宏介绍 函数宏,即包含多条语句的宏定义,其通常为 ...

  9. .net 宏定义_C语言基础知识:几种特殊的函数宏封装方式

    函数宏介绍 函数宏,即包含多条语句的宏定义,其通常为某一被频繁调用的功能的语句封装,且不想通过函数方式封装来降低额外的弹栈压栈开销. 函数宏本质上为宏,可以直接进行定义,例如: #define INT ...

  10. 函数宏定义 与函数自定义

    为什么在C语言中要有函数宏定义这种形式呢?宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等. 在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏 ...

最新文章

  1. 使用runtime让button传递多个参数
  2. 主流机器学习[xgb, lgb, Keras, LR]
  3. docker mysql 容器无故停止的原因
  4. python3 str bytes 字符串 字节 互相转换
  5. Java基础——异常处理
  6. 使用 MWC V2.5 中的 MPU6050中的DMP进行计算姿态(转载)
  7. 编程之美-求数组中最长递增子序列(LIS)方法整理
  8. P4688-[Ynoi2016]掉进兔子洞【莫队,bitset】
  9. python两个时间点比较大小_python中如何比较两个时间点
  10. 不要小看日本的AI公司
  11. 选择排序两层遍历的目的
  12. Delphi之TClientSocket和TServerSocket使用tcp keepalive心跳机制实现“断网”、断电检测...
  13. 手机变身高清摄像头 DroidCamX完全使用教程
  14. 计算机的硬盘e找不到,计算机D驱动器E驱动器突然消失. 小编帮你找回了
  15. 随机出题在线考试系统php_随机出题在线考试系统
  16. 【LaTeX 教程】04. LaTeX 插入数学公式与符号
  17. DEDE源码分析与学习之三: member/archives_*.php文件解读
  18. STM32F103C8T6实现流水灯
  19. 一个新手的评价---人机交互方面(有些不搭题
  20. 什么是JSON(详解)

热门文章

  1. 如何坚持使用程序化系统?
  2. Python实战之Linux 下脚本编写的“奇技淫巧“
  3. JS和JSP之间的区别
  4. 冈萨雷斯DIP第9章知识点
  5. 明朝是中国历史上最有骨气的王朝
  6. 月薪3000,请不要跟我谈狼性文化,谈情怀
  7. 致关闭清华大学软件源的精英的一封信——你们赢了。
  8. 软件协会第01次活动第04次任务布置:爱心代码+数组练习
  9. Android APP第三方支付流程
  10. 6、TELNET终端设计与实现