20个C语言常用宏定义,可防止出错

李肖遥 2023-10-31 08:01
    关注、星标公众号,直达精彩内容
来源:玩转嵌入式


1. 防止一个头文件被重复包含

1#ifndef COMDEF_H
2#define COMDEF_H
3//头文件内容
4#endif

2. 重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。

1typedef unsigned char boolean; /* Boolean value type. */
2typedef unsigned long int uint32; /* Unsigned 32 bit value */
3typedef unsigned short uint16; /* Unsigned 16 bit value */
4typedef unsigned char uint8; /* Unsigned 8 bit value */
5typedef signed long int int32; /* Signed 32 bit value */
6typedef signed short int16; /* Signed 16 bit value */
7typedef signed char int8; /* Signed 8 bit value */

不建议使用:

1typedef unsigned char byte; /* Unsigned 8 bit value type. */
2typedef unsigned short word; /* Unsinged 16 bit value type. */
3typedef unsigned long dword; /* Unsigned 32 bit value type. */
4typedef unsigned char uint1; /* Unsigned 8 bit value type. */
5typedef unsigned short uint2; /* Unsigned 16 bit value type. */
6typedef unsigned long uint4; /* Unsigned 32 bit value type. */
7typedef signed char int1; /* Signed 8 bit value type. */
8typedef signed short int2; /* Signed 16 bit value type. */
9typedef long int int4; /* Signed 32 bit value type. */
10typedef signed long sint31; /* Signed 32 bit value */
11typedef signed short sint15; /* Signed 16 bit value */
12typedef signed char sint7; /* Signed 8 bit value */

3. 得到指定地址上的一个字节或字

1#define MEM_B( x ) ( *( (byte *) (x) ) )
2#define MEM_W( x ) ( *( (word *) (x) ) )

4. 求最大值和最小值

1#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
2#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )

5. 得到一个field在结构体(struct)中的偏移量

1#define FPOS( type, field ) \
2/*lint -e545 */ ( (dword) &(( type *) 0)-> field ) /*lint +e545 */

6. 得到一个结构体中field所占用的字节数

1#define FSIZ( type, field ) sizeof( ((type *) 0)->field )

7. 按照LSB格式把两个字节转化为一个Word

1#define FLIPWray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )

8. 按照LSB格式把一个Word转化为两个字节

1#define FLOPW( ray, val ) \
2(ray)[0] = ((val) / 256); \
3(ray)[1] = ((val) & 0xFF)

9. 得到一个变量的地址(word宽度)

1#define B_PTR( var ) ( (byte *) (void *) &(var) )
2#define W_PTR( var ) ( (word *) (void *) &(var) )

10. 得到一个字的高位和低位字节

1#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
2#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))

11. 返回一个比X大的最接近的8的倍数

1#define RND8( x ) ((((x) + 7) / 8 ) * 8 )

12. 将一个字母转换为大写

1#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )

13. 判断字符是不是10进制的数字

1#define DECCHK( c ) ((c) >= '0' && (c) <= '9')

14. 判断字符是不是16进制的数字

1#define HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\
2((c) >= 'A' && (c) <= 'F') ||\
3((c) >= 'a' && (c) <= 'f') )

15. 防止溢出的一个方法

1#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))

16. 返回数组元素的个数

1#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )

17. 返回一个无符号数n尾的值MOD_BY_POWER_OF_TWO(X,n)=X%(2^n)

1#define MOD_BY_POWER_OF_TWO( val, mod_by ) \
2( (dword)(val) & (dword)((mod_by)-1) )

18. 对于IO空间映射在存储空间的结构,输入输出处理:

1#define inp(port) (*((volatile byte *) (port)))
2#define inpw(port) (*((volatile word *) (port)))
3#define inpdw(port) (*((volatile dword *)(port)))
4#define outp(port, val) (*((volatile byte *) (port)) = ((byte) (val)))
5#define outpw(port, val) (*((volatile word *) (port)) = ((word) (val)))
6#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))

19. 使用一些宏跟踪调试

A N S I标准说明了五个预定义的宏名,其分别是:

1_ L I N E _
2F I L E _
3_ D A T E _
4T I M E _
5_ S T D C _

如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。
_ L I N E __ F I L E _宏指令在有关# l i n e的部分中已讨论,这里讨论其余的宏名。
_ D AT E _宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。
源代码翻译到目标代码的时间作为串包含在_ T I M E _中。串形式为时:分:秒。
如果实现是标准的,则宏_ S T D C _含有十进制常量1。如果它含有任何其它数,则实现是非标准的。
可以定义宏,例如:当定义了_DEBUG,输出数据信息和所在文件所在行。

1#ifdef _DEBUG
2#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)
3#else
4#define DEBUGMSG(msg,date)
5#endif

20. 宏定义防止使用时错误用小括号包含。

例如:

1#define ADD(a,b) (a+b)

do{}while(0)语句包含多语句防止错误,例如:

1#difne DO(a,b) a+b;\
2a++;

应用时:

1if(….)
2DO(a,b); //产生错误
3else

解决方法:

1#define DO(a,b) do{a+b;\
2a++;}
while(0)


版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

关注我的微信公众号,回复“加群”按规则加入技术交流群。


点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

李肖遥 公众号“技术让梦想更伟大”,作者:李肖遥,专注嵌入式,只推荐适合你的博文,干货,技术心得,与君共勉。
评论
  • 全球智能电视时代来临这年头若是消费者想随意地从各个通路中选购电视时,不难发现目前市场上的产品都已是具有智能联网功能的智能电视了,可以宣告智能电视的普及时代已到临!Google从2021年开始大力推广Google TV(即原Android TV的升级版),其他各大品牌商也都跟进推出搭载Google TV操作系统的机种,除了Google TV外,LG、Samsung、Panasonic等大厂牌也开发出自家的智能电视平台,可以看出各家业者都一致地看好这块大饼。智能电视的Wi-Fi连线怎么消失了?智能电
    百佳泰测试实验室 2024-12-12 17:33 90浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-12 10:13 62浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-11 17:58 98浏览
  • 本文介绍瑞芯微RK3588主板/开发板Android12系统下,APK签名文件生成方法。触觉智能EVB3588开发板演示,搭载了瑞芯微RK3588芯片,该开发板是核心板加底板设计,音视频接口、通信接口等各类接口一应俱全,可帮助企业提高产品开发效率,缩短上市时间,降低成本和设计风险。工具准备下载Keytool-ImportKeyPair工具在源码:build/target/product/security/系统初始签名文件目录中,将以下三个文件拷贝出来:platform.pem;platform.
    Industio_触觉智能 2024-12-12 10:27 93浏览
  • 一、SAE J1939协议概述SAE J1939协议是由美国汽车工程师协会(SAE,Society of Automotive Engineers)定义的一种用于重型车辆和工业设备中的通信协议,主要应用于车辆和设备之间的实时数据交换。J1939基于CAN(Controller Area Network)总线技术,使用29bit的扩展标识符和扩展数据帧,CAN通信速率为250Kbps,用于车载电子控制单元(ECU)之间的通信和控制。小北同学在之前也对J1939协议做过扫盲科普【科普系列】SAE J
    北汇信息 2024-12-11 15:45 120浏览
  • 首先在gitee上打个广告:ad5d2f3b647444a88b6f7f9555fd681f.mp4 · 丙丁先生/香河英茂工作室中国 - Gitee.com丙丁先生 (mr-bingding) - Gitee.com2024年对我来说是充满挑战和机遇的一年。在这一年里,我不仅进行了多个开发板的测评,还尝试了多种不同的项目和技术。今天,我想分享一下这一年的故事,希望能给大家带来一些启发和乐趣。 年初的时候,我开始对各种开发板进行测评。从STM32WBA55CG到瑞萨、平头哥和平海的开发板,我都
    丙丁先生 2024-12-11 20:14 86浏览
  • 时源芯微——RE超标整机定位与解决详细流程一、 初步测量与问题确认使用专业的电磁辐射测量设备,对整机的辐射发射进行精确测量。确认是否存在RE超标问题,并记录超标频段和幅度。二、电缆检查与处理若存在信号电缆:步骤一:拔掉所有信号电缆,仅保留电源线,再次测量整机的辐射发射。若测量合格:判定问题出在信号电缆上,可能是电缆的共模电流导致。逐一连接信号电缆,每次连接后测量,定位具体哪根电缆或接口导致超标。对问题电缆进行处理,如加共模扼流圈、滤波器,或优化电缆布局和屏蔽。重新连接所有电缆,再次测量
    时源芯微 2024-12-11 17:11 123浏览
  • 应用环境与极具挑战性的测试需求在服务器制造领域里,系统整合测试(System Integration Test;SIT)是确保产品质量和性能的关键步骤。随着服务器系统的复杂性不断提升,包括:多种硬件组件、操作系统、虚拟化平台以及各种应用程序和服务的整合,服务器制造商面临着更有挑战性的测试需求。这些挑战主要体现在以下五个方面:1. 硬件和软件的高度整合:现代服务器通常包括多个处理器、内存模块、储存设备和网络接口。这些硬件组件必须与操作系统及应用软件无缝整合。SIT测试可以帮助制造商确保这些不同组件
    百佳泰测试实验室 2024-12-12 17:45 88浏览
  • RK3506 是瑞芯微推出的MPU产品,芯片制程为22nm,定位于轻量级、低成本解决方案。该MPU具有低功耗、外设接口丰富、实时性高的特点,适合用多种工商业场景。本文将基于RK3506的设计特点,为大家分析其应用场景。RK3506核心板主要分为三个型号,各型号间的区别如下图:​图 1  RK3506核心板处理器型号场景1:显示HMIRK3506核心板显示接口支持RGB、MIPI、QSPI输出,且支持2D图形加速,轻松运行QT、LVGL等GUI,最快3S内开
    万象奥科 2024-12-11 15:42 96浏览
  • 在智能化技术快速发展当下,图像数据的采集与处理逐渐成为自动驾驶、工业等领域的一项关键技术。高质量的图像数据采集与算法集成测试都是确保系统性能和可靠性的关键。随着技术的不断进步,对于图像数据的采集、处理和分析的需求日益增长,这不仅要求我们拥有高性能的相机硬件,还要求我们能够高效地集成和测试各种算法。我们探索了一种多源相机数据采集与算法集成测试方案,能够满足不同应用场景下对图像采集和算法测试的多样化需求,确保数据的准确性和算法的有效性。一、相机组成相机一般由镜头(Lens),图像传感器(Image
    康谋 2024-12-12 09:45 100浏览
  • 铁氧体芯片是一种基于铁氧体磁性材料制成的芯片,在通信、传感器、储能等领域有着广泛的应用。铁氧体磁性材料能够通过外加磁场调控其导电性质和反射性质,因此在信号处理和传感器技术方面有着独特的优势。以下是对半导体划片机在铁氧体划切领域应用的详细阐述: 一、半导体划片机的工作原理与特点半导体划片机是一种使用刀片或通过激光等方式高精度切割被加工物的装置,是半导体后道封测中晶圆切割和WLP切割环节的关键设备。它结合了水气电、空气静压高速主轴、精密机械传动、传感器及自动化控制等先进技术,具有高精度、高
    博捷芯划片机 2024-12-12 09:16 97浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦