前言

在C语言中,对于一些常用或通用的代码段的封装可以有两种方式:函数宏定义

这篇博客就来带大家梳理一下对于这两种方式我们在使用时应该如何抉择,以及它们的区别和优缺点。

宏定义和函数的区别

  • 从程序的执行来看:

函数调用需要开辟和释放栈空间带来开销(存在函数调用压栈和返回的额外开销),不仅会降低代码效率,而且代码量也会大大增加。
宏定义只在编译前进行,不分配空间,不占运行时间。

总结:宏定义在代码规模和速度方面都比函数更胜一筹

  • 从参数的类型来看:

函数的参数必须声明为一种特定的数据类型,如果参数的类型不同,就需要使用不同的函数来解决。
宏定义的参数是无类型的,只要参数的操作是合法的,它可以用于任何参数类型。

总结:宏定义是类型无关的,较函数应用更为广泛

  • 从参数的副作用来看:

宏定义中对宏参数缺少必要的类型检查,宏的参数和返回值最好用()括起来,否则可能导致返回值和预期的结果不符,宏的参数如果传入自增自减型,则返回值也可能和预期不符。
函数则从根本上避免了这些问题的发生。

举个栗子:

#define MAX(a,b) ((a)>(b)?(a):(b))
x = 5;
y = 8;
z = MAX(x++,y++);
printf("x=%d y=%d z=%d,x,y,z);输出结果:6 10 9

解析:

1.宏替换:MAX ( (x++) > (y++) ? (x++) : (y++) )
2.比大小:5 > 8 结果为假(此时后置++操作x=6,y=9),返回y,此时后置++操作y=10
3.输出:x=6,y=10,z为返回值(也就是y++之前的值)z=9

  • 从代码的长度来看:

宏定义使用时,代码的副本会插入程序中,除非宏非常短,否则使用宏会大幅度地增加程序的长度,并且宏是不方便调试且不能递归的。
函数代码则只会出现在一个地方,以后每次调用这个函数时,调用的都是那个地方的同一份代码

总结:宏定义的使用相较函数来说可能会大幅度增加程序的长度

从上面的四点分析:

函数和宏定义各有优缺点,这就要求我们根据具体情况具体分析,合理地对二者进行取舍

小结

综上所述,如何取舍这二者,还需要根据具体情况具体分析,千万不能够武断地做出判断。一般来说,应该用宏去替换小的、可重复的代码段,这样可以使程序运行速度更快。当任务比较复杂,需要多行代码才能实现时,或者要求程序越小越好时,就应该使用函数

C语言中宏定义和函数的区别相关推荐

  1. C语言中宏定义和函数的取舍

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

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

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

  3. 如何用C语言改变宏定义的大小,C语言中宏定义使用的小细节

    C语言中宏定义使用的小细节 #pragma#pragma 预处理指令详解 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#p ...

  4. C/C++编程笔记:浅析 C 语言中宏定义的使用,知识点全解

    宏定义是用一个标识符来表示一个字符串,在宏调用中将用该字符串代替宏名.给程序员提供了便利,使程序更加清晰,便于阅读和理解,进一步提高了程序的运行效率,对于嵌入式系统而言,为了能达到性能要求,宏是一种很 ...

  5. c语言中宏定义的字符替换#define M(x,y,z) x*y+z

    C语言中宏定义的字符替换问题 例子: 在c语言中定义如下宏 #define M(x,y,z) x*y+z 给定如下程序 #include<stdio.h> #include<stdl ...

  6. C语言中宏定义的使用

    1. 引言 1.1 宏定义的基本语法 1.2 宏定义的优点 1.3 宏定义的缺点 1.4 宏还是函数 2 使用宏时的注意点 2.1 算符优先级问题 2.2 分号吞噬问题 2.3 宏参数重复调用 2.4 ...

  7. C语言中宏定义使用方法详解

    C语言中的宏替换详解 首先看一个问题: #include <stdio.h> #define    PRINT_CLINE()    printf("%d", ____ ...

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

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

  9. C语言中宏定义宏编译的使用#if,#ifdef,#ifndef,#elif,#else,#endif,defined使用详解,可以实现和if else一样的效果

    #define            定义一个预处理宏 #undef            取消宏的定义 #if                   编译预处理中的条件命令,相当于C语法中的if语句 ...

最新文章

  1. 中过滤记录中时间_水肥一体化中常见的过滤器
  2. Intel Realsense D435 关于开放环境下的目标识别 曝光量参数的自动设定机制
  3. linux下使用yum安装新版php7.0
  4. 显式锁select for update 用法
  5. 数据库ORA-03113排查
  6. 陈天艺1636050045假设跑步者1小时40分钟35秒跑了24英里。编写一个程序显示每小时以公里为单位的平均速度值...
  7. .NET Core开发实战(第28课:工作单元模式(UnitOfWork):管理好你的事务)--学习笔记...
  8. Java Singleton设计模式
  9. 矩阵特征值的物理意义
  10. SQL注入攻击与防御
  11. JDK8升至JDK11 新特性整理
  12. oss客户端工具_云享会 | 沃云公有云重点产品推荐:文件存储NASamp;对象存储OSS...
  13. 无线网卡dns服务器地址怎么查询,技术编辑教你win10系统查看无线网卡DNS、IP地址的设置教程...
  14. vue中echarts使用案例:饼图(可直接使用)
  15. PyTorch 11—简单图像定位
  16. 【原创】从头开始,使用安卓系统WebView做一个功能强大的Epub阅读器(二)
  17. 神思通用100型读身份证
  18. envato elements国外设计网站素材代服务包月包年VIP高速下载
  19. 考研英语——唐迟阅读方法技巧总结
  20. SQL Server研习录(29)——sql server 设置列自增长

热门文章

  1. 自己做一个table插件 (一)Ajax获取数据后动态生成table
  2. 嵌入式主板分类及优点
  3. oracle数据库之统计分析(方差、标准差、协方差)
  4. Matlab_回归分析_逐步回归
  5. Linux系统编程之捕捉SIGCHLD
  6. Python plot() 画图标记 marker
  7. python 获取屏幕颜色_Python3 获取手机屏幕指定坐标点的 RGBA 和 16 进制颜色
  8. Ubuntu16.04 安装docker-ce [傻瓜教程]
  9. 关机程序源代码——千万不要点运行!!!hahaha
  10. [EOS源码分析]7.EOS智能合约开发实践之合约调用合约(inline action)