很多人不理解宏的概念,其实这与翻译有很大关系,
如果将 macro
理解为 缩写
,就更易懂了,翻译成缩变
就更合适了。
自然语言中,缩写
是简单的替换,
人大
就是人民代表大会
,
中共
就是中国共产党
,
GDP
就是Gross Domestic Product
,翻译过来就是国内生产总值
,
编程语言中也存在类似的概念,这就是我们说的宏
。
什么是宏?
在编程语言中,macro
(macro instruction 的简称) 是将某些输入替换成某些输出的规则,
它的输入、输出类型可以是字符、词法 token 或者语法树。
宏可以携带参数,一个或者多个,根据参数的不同,替换为不同的内容,也就是可编程替换
。
编程语言中涉及宏的地方有两种:
- 宏的定义:用来定义替换规则
- 宏的展开:用宏的替换规则将宏的输入展开成宏的输出
宏示例
许多编程语言有宏的概念,比如 C,TeX,m4,lisp,scheme,julia,scala,rust,以及某些汇编语言等等, 下面我们用 C 语言中的宏来示例宏定义和用法。
比如在 C 语言中定义一个简单的 max
宏如下:
#define max(a,b) ((a) >= (b) ? (a) : (b))
这里定义了一个名为 max
的宏,
这个宏有两个参数是 a
和 b
,
而后面的 ((a) >= (b) ? (a) : (b))
用来规定替换 max(a, b)
形式的输出样式。
当在代码中使用 max
宏的时候,根据参数的不同进行替换相应的代码,
比如下面的代码:
i + max(x*y, u-v) + j
这里 max(x*y, u-v)
就相当于一个编程语言 缩写
,
其中 x*y
会匹配到 max 定义中的 a
参数,而 u-v
就匹配到 max 定义中的 b
参数,
max(x*y, u-v)
| |
| |
v v
max( a , b )
然后根据 max 定义,将 max(a, b)
形式的宏调用进行参数替换:
(( a ) >= ( b ) ? ( a ) : ( b ))
| | | |
| | | |
v v v v
((x*y) >= (u-v) ? (x*y) : (u-v))
整个 i + max(x*y, u-v) + j
最终替换后的结果是:
i + ((x*y) >= (u-v) ? (x*y) : (u-v)) + j
更复杂的宏
当然,C 语言中的宏还是比较简单的,它仅仅是词法 token 级别的替换, 有些编程语言有更复杂,更具有编程性的宏, 它们中的代表是 lisp 语言,lisp 可以说是对宏应用最彻底的一个语言, 这与 lisp 的语法是 sexp(S-expressions, Symbolic EXPression)有关, 具体需要看下一篇博文了。