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

先看宏

宏: #define 机制包括了一个规定,允许把参数替换到文本中,这种实现常常称为宏,或者宏定义。

宏对变量的副作用:

#define SQUARE(x)  (x * x)     //常见的求平方

然后求平方

SQUARE(5)

预处理器就会用  5 * 5 这个表达式替换上面的表达式,结果是 25,符合你的预期。

但是请看下面一个:

int a = 5;
printf(" (5 + 1) square: %d\n", SQUARE( 5 + 1));
结果是:11    不符合你的预期实际在执行时, 使用 5 + 1 * 5 + 1 替换了上面的表达式, 结果就是11, 不符合你的预期, 这种是最常见的相邻的操作符优先级, 大于你传入参数需要优先执行操作符的优先级.
类似的还有 a++ 这样的操作, 都会带来副作用.

宏对参数的副作用,在使用自定义函数时就不会产生:

int get_square(int a)
{return a*a;
}调用 get_square(5+1)时, 不会产生参数的副作用, 程序执行时, 会先算出5+1的和, 然后再传入函数去执行。

先看一下《C与指针》中的宏定义“函数”与自定义接口的区别:

  宏与函数的区别
属性 #define 宏 函数
代码长度

每次调用时,宏代码都会被插入到程序中。除了非常小的宏之外,程序的长度将大幅增加

函数代码只出现在一个地方,每次调用这个函数时,调用的都是那个地方的同一份代码
执行速度 更快 存在函数调用/返回的额外开销
操作符优先级

宏参数的求值是在所有周围下上文环境里,除非给它们加上括号,否则邻近操作符的优先级,可能会产生不可预测的结果

函数参数只在函数调用时求值一次,它的结果值传递给函数。表达式的求值更容易预测。

参数求值

参数每次用于宏定义时。它们都将重新求值,由于多次求值,具有副作用的参数可能会产生不可预料的结果。

参数在函数被调用前只求值一次,在函数中多次使用参数,并不会导致多种求值过程,参数的副作用并不会造成任何特殊问题

参数类型 宏与类型无关,只要参数的操作是合法的,它可以适用于任何参数类型

函数的参数是与类型有关的,如果参数的类型不同,就需要使用不同的函数,即使它们的任务是相同的

我们常用到的比较大小,宏定义:

#define MAX( a, b) ( (a) > (b) (a) : (b) )

自定义接口实现就是:

int max( int a, int b)
{return (a > b a : b)
}

区别:

1. 最直观的来讲,自定义的函数已经指定了类型,只能比较两个整数的大小,却不能再去比较浮点数的大小,或者两个ASCII码的大小;而宏定义是不会限定类型的,只要比较的类型一致即可。

2. 自定义接口在程序运行时,会产生临时的堆空间,有临时的空间消耗,如果是递归的话,需要的临时栈空间可能更多;宏定义是在程序运行时,会将宏定义这段代码插入到程序中执行,会有额外的代码段。

3. 自定义接口在调用时,实际的开销要比代码段大,规模更大; 而宏比自定义函数在程序的规模和速度方面,比自定义函数更胜一筹。

C语言【宏定义与函数的区别】相关推荐

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

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

  2. C语言宏定义制作函数模板

    一.介绍 当做协议栈或者批量化函数的时候,内容框架是固定的,如果要写1000个10000个函数确实手敲比较麻烦,一种是用工具批量产生这些函数,另一种就是宏定义,这里给出宏定义解决的方法,利用宏定义制作 ...

  3. C语言带参宏定义和函数的区别

    带参数的宏和函数区别: 宏展开仅仅是字符串的替换,不会对表达式进行计算:宏在编译之前就被处理掉了,它没有机会参与编译,也不会占用内存.而函数是一段可以重复使用的代码,会被编译,会给它分配内存,每次调用 ...

  4. c语言 宏定义swap函数,C++ 用宏实现swap(a,b)

    sql语句注意事项 1两表根据a字段关联,把t2表中的c字段值更新到t1表中的c字段update T1set T1.C =(select T2.C from T2 where T1.A = T2.A) ...

  5. c语言宏编译命令大全,C语言宏定义与预编译详解

    http://blog.csdn.net/findaway123/article/details/6994203 2011 1.宏定义和函数的区别 -------------------------- ...

  6. C语言宏定义、宏函数、内置宏与常用宏

    前言: 在C语言中,变量类型.循环控制.基础语法等与其他高级语言基本无异:而C语言(C++)特有的两把双刃剑指针和宏定义/宏函数使得C语言在底层开发中披荆斩棘.无所不能.这两个概念涉及范围比较广,其分 ...

  7. C语言-宏定义#define的用法

    目录 1 不带参宏定义 2 带参宏定义 3 与字符串有关的用法 3.1 字符串转换 3.2 字符转换 3.3 字符连接 1 不带参宏定义 这种用法是最简单最常见的一种方式,如下: #define PA ...

  8. ANSI C and Microsoft C++中常用的预定义宏以及 宏定义中 # 和 ## 的区别

    ANSI C and Microsoft C++中常用的预定义宏以及 宏定义中 # 和 ## 的区别 第一部分,常见的预定义宏 第二部分,# 和 ## 再宏定义中的使用说明 第三部分,类似 #prag ...

  9. 宏定义 指针 c语言,C语言宏定义讲解(C和指针 笔记)

    关于C语言宏定义#define 最常用的莫过于通过宏定义定义常数了,例如 #define MAX 1000      通过宏定义程序中需要的常量,方便维护被多次引用的变量,并且宏替换在预处理阶段完成, ...

最新文章

  1. 一文详解激光点云的地面分割
  2. QIIME 2教程. 09数据导入Importing data(2020.11)
  3. mysql 运算符 =,:=,@,@@的含义
  4. 数据蒋堂 | 报表工具的SQL植入风险
  5. python 三角函数
  6. 【Android 逆向】Android 系统文件分析 ( 外部存储设备文件 | sbin 命令程序目录 | dev 字符设备目录 )
  7. 连接相机无法识别_车牌识别一体机在汽修门店安装中要注意的事项
  8. 持续更新的Zookeeper知识总结
  9. c++面向对象高级编程 学习三 堆、栈和内存泄漏
  10. spring-security-学习笔记-01-基本概念
  11. 计算机SCI期刊征稿 | 影响因子最高10+,一区,毕业/评职称不要错过!
  12. Linux命令行报错 bash: cannot create temp file for here-document: No space left on device
  13. 计算机房安全防范措施,机房安全防护方案
  14. 《麦肯锡方法》学习笔记18
  15. Excel2016如何添加表格边框?分享技巧!怎样在excel加入表格边框?
  16. word“您的组织策略阻止我们为您完成此操作”解决记录
  17. Android 百度翻译API(详细步骤+源码)
  18. 文件包含小总结 By Assassin
  19. 解决no session问题的三种方式
  20. oracle10g 学习笔记上

热门文章

  1. 嵌入式主板上使用的插针式加密锁
  2. VMware Workstation 15 pro 安装macOS 10.13,macOS 10.14教程(仅供个人兴趣学习使用)
  3. 社区发现算法原理与louvain源码解析
  4. 一个好的web前端开发者,是怎么学习的?前端开发培训机构哪个比较好
  5. 面试高级算法梳理笔记
  6. android关闭触摸声音,如何在Android中关闭所有触摸声音 | MOS86
  7. 【新手向】centOS 7 linux虚拟机联网具体步骤
  8. 多表联查--01---LEFT JOIN 实现多表联查
  9. 计算雅思成绩C语言,雅思考试总成绩计算查分表
  10. 视频监控系统由哪几部分组成?(视频监控入门基础-附思维导图)