你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

一些成熟软件中常用的宏定义

[复制链接]
gaosmile 发布时间:2021-1-15 11:26
写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性等等。下面列举一些成熟软件中常用的宏定义。1. 防止一个头文件被重复包含1#ifndef COMDEF_H& ~# y. u0 K- i+ N- T1 A' j
2#define COMDEF_H' U4 y) X7 Q' f/ B% z* N: T' H
3//头文件内容7 ^7 Z/ [6 R3 {% G7 D" }
4#endif" ^5 t; v5 E3 p4 ]
2. 重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。1typedef unsigned char boolean; /* Boolean value type. */: F2 N5 E0 X. c$ [7 {0 Y2 P% D: F- T
2typedef unsigned long int uint32; /* Unsigned 32 bit value */; R% P1 e- E" z2 K1 A
3typedef unsigned short uint16; /* Unsigned 16 bit value *// I, }1 @# L' K
4typedef unsigned char uint8; /* Unsigned 8 bit value */
) a2 h0 }3 i- A8 t$ b5typedef signed long int int32; /* Signed 32 bit value */* f0 Y! f5 }; G
6typedef signed short int16; /* Signed 16 bit value */
% J: g* x$ T/ w, w; d7typedef signed char int8; /* Signed 8 bit value */, E' _, E6 D6 v' w. w
下面的不建议使用
1typedef unsigned char byte; /* Unsigned 8 bit value type. */! m- A% i, E, ^7 L8 f( L# i
2typedef unsigned short word; /* Unsinged 16 bit value type. */
7 U& Z4 c7 p7 p) }8 v/ u/ z1 T5 _4 @ 3typedef unsigned long dword; /* Unsigned 32 bit value type. */
7 e/ W$ N' O5 X+ m+ @3 v 4typedef unsigned char uint1; /* Unsigned 8 bit value type. */# `' v1 L% Q$ {# s3 X* V" u
5typedef unsigned short uint2; /* Unsigned 16 bit value type. */
6 U1 u, A  i7 J 6typedef unsigned long uint4; /* Unsigned 32 bit value type. */: _9 r* Z% h% i# u8 D) Y
7typedef signed char int1; /* Signed 8 bit value type. */+ \2 f0 @: m: v" Z- s# z" w2 ]
8typedef signed short int2; /* Signed 16 bit value type. */
: E; I! Y( p) b, h- c  s7 b, V  f- M6 t 9typedef long int int4; /* Signed 32 bit value type. */% h6 i' ?6 n& f9 V$ W
10typedef signed long sint31; /* Signed 32 bit value */  i2 Q1 _2 s9 e, I% A, V' J
11typedef signed short sint15; /* Signed 16 bit value */0 t, ?2 P" p# Z' v
12typedef signed char sint7; /* Signed 8 bit value */
2 k& V( O! o4 N
3. 得到指定地址上的一个字节或字1#define MEM_B( x ) ( *( (byte *) (x) ) )0 p$ G4 n$ R& L2 h( B" h# [0 a% D0 t9 {
2#define MEM_W( x ) ( *( (word *) (x) ) )# b; ~% j$ q7 z
4. 求最大值和最小值1#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
+ G1 D& f# F! u" O% q' j2#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )$ x1 i. i5 Z. T; `4 j2 P3 e
5. 得到一个field在结构体(struct)中的偏移量1#define FPOS( type, field ) \' E- ]! r& ?7 M3 [& B3 v" Z
2/*lint -e545 */ ( (dword) &(( type *) 0)-> field ) /*lint +e545 */
2 b) G) ?9 J9 }/ N
6. 得到一个结构体中field所占用的字节数1#define FSIZ( type, field ) sizeof( ((type *) 0)->field )' Y1 X7 u$ h* j' n" n  r
7. 按照LSB格式把两个字节转化为一个Word1#define FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )
8 g8 ^* S7 g* \3 R" p6 M- M0 ]
8. 按照LSB格式把一个Word转化为两个字节1#define FLOPW( ray, val ) \
# b+ w9 Z+ i" ]# y5 R* j2(ray)[0] = ((val) / 256); \
" o3 U& E" C7 t6 b3(ray)[1] = ((val) & 0xFF)
( x5 U3 r0 S: }# k% n
9. 得到一个变量的地址(word宽度)1#define B_PTR( var ) ( (byte *) (void *) &(var) )
  d: p2 }+ Z1 ^6 _3 ?2#define W_PTR( var ) ( (word *) (void *) &(var) )
7 `5 T  O" B8 N( z) w
10. 得到一个字的高位和低位字节1#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))/ N9 p5 X. u$ n
2#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))
: s! r3 U+ T1 Z4 [$ p- B" o- e1 L
11. 返回一个比X大的最接近的8的倍数1#define RND8( x ) ((((x) + 7) / 8 ) * 8 )
$ e) w# o' a, D1 z- `$ E
12. 将一个字母转换为大写1#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )5 S2 _" ?& G) }; z* F' q. A
13. 判断字符是不是10进制的数字1#define DECCHK( c ) ((c) >= '0' && (c) <= '9')
+ s1 M4 e; q0 _* Z
14. 判断字符是不是16进制的数字1#define HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\
+ b! z% p7 U! I: ~2((c) >= 'A' && (c) <= 'F') ||\
8 Q+ i, k; A/ |) S1 J1 A- ^3((c) >= 'a' && (c) <= 'f') )2 w$ J3 E; c( Q
15. 防止溢出的一个方法1#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))6 E0 O0 B( s: z0 K
16. 返回数组元素的个数1#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
$ C: J! c& E; M) e# K! N% q* R, E3 x
17. 返回一个无符号数n尾的值MOD_BY_POWER_OF_TWO(X,n)=X%(2^n)1#define MOD_BY_POWER_OF_TWO( val, mod_by ) \
0 @$ |1 x  ^8 n3 N, J1 K/ @/ [. ^2( (dword)(val) & (dword)((mod_by)-1) )
! r- h8 h0 i4 @; y$ @2 J
18. 对于IO空间映射在存储空间的结构,输入输出处理1#define inp(port) (*((volatile byte *) (port)))
( P- T# V( z! y. v& f2#define inpw(port) (*((volatile word *) (port)))7 T, O/ s6 W- ?! q. z/ Y  ~
3#define inpdw(port) (*((volatile dword *)(port)))& K: c9 ?, O* |. y3 J: C9 s# Z1 `% q- o
4#define outp(port, val) (*((volatile byte *) (port)) = ((byte) (val)))$ e, G- y: }/ ~: i1 q2 B
5#define outpw(port, val) (*((volatile word *) (port)) = ((word) (val)))  {7 E3 b% n2 W5 o3 h& @: y
6#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))
) V* r8 @7 _+ k' i
19. 使用一些宏跟踪调试
A N S I标准说明了五个预定义的宏名。它们是:
1_ L I N E _
' x2 v" k3 v/ L6 E8 @2 Y2_ F I L E _
1 n8 t% n: m! h3_ D A T E _
) s3 w4 |: Z) F' Z& B5 [4_ T I M E _
9 v7 W5 d: q: L. B) x# h9 s5_ S T D C _+ y7 E; K- w& x% ^
如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。
_ 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# o: ?$ i5 t6 g  A$ z. I
2#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)
1 K2 c% V6 U. O8 q& O3#else
* j7 k; i- _: i" X4#define DEBUGMSG(msg,date)5 i$ _- l7 J  B4 L5 a# i: M
5#endif
) |0 M: w4 `% X, M2 I4 P! Y9 \1 J8 z
20. 宏定义防止使用时错误用小括号包含。
例如:
1#define ADD(a,b) (a+b)$ s) u2 V% x5 p) i) e  t& {
用do{}while(0)语句包含多语句防止错误
例如:
1#difne DO(a,b) a+b;\) {- B) T0 n. O0 F1 X8 k* s: F9 @
2a++;
6 k/ S# }; C  {' n
应用时:
1if(….)) v+ c% h( R  v9 S3 O
2DO(a,b); //产生错误2 l% H6 `9 v! O6 K/ ]# x) \
3else2 O/ a# F( O$ z/ E* h
解决方法:
1#difne DO(a,b) do{a+b;\
6 {8 D' p: t0 z6 k2a++;}
while(0)

$ q2 y& J0 E7 E) ~
赞 收藏 评论0 发布时间:2021-1-15 11:26

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版