1.说到伪指令宏一般就会联想到指令、宏指令和伪指令。
6 ^& W* @ `' X& H9 S l先借用别人的话简单介绍一下三者之间的关联和区别(看到一个博主写的很不错):% b _/ i' D) ]2 S
我们使用的各种指令,都是写给“编译软件”看的。
3 \4 O t- e* m9 m要由“编译软件”翻译成计算机可以识别的机器语言,即机器码。
* C, s- a6 l/ l. U, Y, C1 w2 h7 N. H* R$ b9 c3 e
通俗地讲:
( s& ?9 z4 C. U- F8 W6 s就好像召开新闻发布会,主持人用中文讲话,由一个翻译,现场翻译成英文,讲给外国记者听。9 R9 a$ b$ [$ I9 O2 c
主持人说的中文,大部分都是要翻译成英文的;少数几句,是说给翻译听的,告诉他如何翻译。
H1 w. N& U6 S( }* ^; b. u/ L& Q5 ?# C5 V. F
我们写的指令,由“编译软件”翻译成机器码的,称为指令语句;/ z( j, K T( l8 f3 S
有一些是写给“编译软件”看的,不翻译成机器码,这样的就是“伪指令”。
% V5 N+ E' a0 u( L4 ?0 o G; ~; w9 D: Y( W8 h1 r) S( v8 b9 _+ _
一条条计算机的指令,一般来说,功能都是极为简单的。我们可以把几条、几十条指令,编写成一个“宏指令”,来完成一个比较复杂的任务。) v, i% h% d3 x [
在这样“一批指令”的前面,要用一条“伪指令”来命名这个“宏指令”;$ Y8 i* W- B1 G7 k7 Z0 \
在后面,要用一条“伪指令”说明结尾。
6 z- ^+ c9 |# j9 V# [以后,这个“宏指令”,就可以当成 正式指令 来使用了。
7 Y3 p% e0 m& r5 k3 t$ s( j) G: n" o2 u4 r( D
2.伪指令宏分为简单宏、参数宏、条件宏、预定义宏和宏释放
- z0 x# G9 u# H: U简单宏:& i1 [8 Q8 }& ?8 E
定义格式: #define 宏标识符 宏体3 `" R$ G5 c* H8 M4 z1 X' r, H
是最常见的宏,在宏体长的时候使用续行符“\”连接宏体,如示
& I# O: T3 y g8 p8 F. ?" s4 z8 J- #define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \! `6 g# W( n% v
- ((PERIPH) == GPIOB) || \
+ P+ W' I$ a; ~# i1 ?# r' k - ((PERIPH) == GPIOC) || \
! D; [+ U/ S* Q( D- N$ c) J L - ((PERIPH) == GPIOD) || \, Y# |" l' r9 K F1 p
- ((PERIPH) == GPIOE) || \0 H; `; ?3 ~3 B. ]' r4 T+ Q
- ((PERIPH) == GPIOF) || \( x" [$ a! V: I$ O6 n% X
- ((PERIPH) == GPIOG))9 ]# K$ Y6 _ h4 Q& C0 d4 k i
复制代码
: I( m3 P" r, N- K! |宏的用法:在源文件中,用预处理器伪指令定义过宏标识符后,就可以用宏标识符编写程序。当源文件被预处理器处理时,每遇到该宏标识符,预处理器便在宏的所在处将宏扩展为宏体。
K$ {1 ?1 b: @7 Q. r% y参数宏:6 [" W: R+ f" f5 F& Q' w
定义格式:#define 宏标识符(形式参数表) 宏体
9 |2 f( J& o- S |/ H! \形式参数表为逗号分割的形式参数,宏体可以用“\”进行续行,使用参数宏时形式参数被换为相同个数的实参数表。(类似于函数的调用,实际上许多库函数时用参数宏编写的。二者区别是参数宏的形式参数表中没有类型说明符)
% ^ D# I& S% C2 h' N* E) o5 p( n' y8 m. E! t2 }. x/ s/ y6 D0 L
举例如示% A- B9 M* w* @0 y+ ^$ p, `
- #define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \
' y5 J* u1 S; B+ Z b - ((PIN) == GPIO_Pin_1) || \
9 V: N4 F) g o) \ [ - ((PIN) == GPIO_Pin_2) || \
6 n# J' D/ ]9 H - ((PIN) == GPIO_Pin_3) || \
X( h: m9 b" G' L8 ^ q) [" | - ((PIN) == GPIO_Pin_4) || \
' L+ h4 n6 A* I; t, _ - ((PIN) == GPIO_Pin_5) || \
8 D8 {5 H3 a5 r* o - ((PIN) == GPIO_Pin_6) || \
2 ^* k3 ?$ d; J# P$ ?% A& P! B - ((PIN) == GPIO_Pin_7) || \
5 h: }2 K# n& x) E! r: N - ((PIN) == GPIO_Pin_8) || \4 E& P- g9 ?- Z% k: E M9 \
- ((PIN) == GPIO_Pin_9) || \
* k$ a" [% X$ \0 ? { - ((PIN) == GPIO_Pin_10) || \
# B4 U5 ?# p0 t* q - ((PIN) == GPIO_Pin_11) || \ @( g, a- O3 J2 D1 H; n
- ((PIN) == GPIO_Pin_12) || \1 c5 d7 a9 y0 W( W* p, R6 ~/ u- Q
- ((PIN) == GPIO_Pin_13) || \
8 G$ F0 d! `0 I8 f7 ? - ((PIN) == GPIO_Pin_14) || \
+ H4 v+ `3 Z$ t - ((PIN) == GPIO_Pin_15))* }5 Q D6 G3 n# w$ H
复制代码 3 L4 }( x$ \' |- ]0 _: x
预处理器在处理参数宏时使用俩次宏展开。第一次展开宏体,第二次对展开的宏体用实参数替换形式参数。( [5 G4 x. e4 _8 X
$ p3 ], u( ~/ e) E8 T) U宏释放:
! [- i' _# B r9 K1 }- H% y定义格式: #undef 宏标识符
/ E3 T i5 i9 c用于释放原定义的宏标识符,释放后的宏标识符可以再次用于定义其他宏体。6 d) C4 ?: ^3 T# W
) ]" g8 x; h, P$ F/ v% J条件宏定义:0 x# F3 F. g6 E) F* w# H- h$ H" Y
条件宏定义主要是用来测试是否定义过某宏标识符,以及决定如何处理宏标识符,具体格式有俩种:3 H: w5 x2 I' Q0 y
- \\测试存在情况
5 S& `- K! ^0 o! l - #ifdef 宏标识符
* u: f0 m" b7 u - #undef 宏标识符# [ h# G4 U+ H7 ]
- #define 宏标识符 宏体
- n3 f2 v5 N5 K- v1 u# K - #else4 U" Z0 _8 r& q: A" v
- #define 宏标识符 宏体3 h+ H* j; ]# x% K$ l( m
- #endif- ^7 c9 u/ O6 l4 s. D
: |* V' W" Z* g9 T/ i- \\测试不存在情况
) e2 S8 a4 }1 c2 s M B" s. [ - #ifndef 宏标识符
2 _. w9 S+ k% f5 V! Q - #define 宏标识符 宏体
' D/ m P: m+ \1 x7 u. `" Q! ~ - #else
+ Q6 j+ B' z0 T& C3 T# h - #undef 宏标识符4 D- K/ i# X8 Q" v5 V9 `2 `$ R
- #define 宏标识符 宏体" n! s# a$ z2 u! F2 I
- #endif+ Z/ @0 t# n P6 j9 _7 p {8 D
复制代码
# w$ K8 L/ b/ ]0 J2 i常用于头文件中。! u+ H5 j' W! B) v1 S% J8 u# G
4 N+ Z& D( S; ?' _: I预定义宏:% b0 a4 u" F2 {; @
预定义宏基本莫得存在感,其特征就是标识符前后都有双下划线。如1 p5 G, D8 z' Q0 C; M0 Z. C
- __DATE__ __TIME__7 ~7 }. ?/ Y$ m* ~- ?( A; {! R; p
- __FILE__ __LINE__
. X! g+ c! A3 _6 B2 }: E# X% W - __STDC__6 _) W9 J3 H) g. l, m, }# X: z( g
复制代码 * }. F$ q& r7 Y% ~0 |
这些预定义宏的宏体分别是当时的日期、时间、所在文件名、所在文件的行数。
2 f; P! m8 o0 Y* J1 J5 [3 X2 A————————————————
e8 ^( F. ^1 x: Y版权声明:Aspirant-GQ
* u' g* c1 l6 v" F6 U& E, R' w如有侵权请联系删除
2 d- f2 W" Y% l* P* m/ ^6 w) b$ T
, J. [& `0 c% `( r. D3 e; P; Q |