python实现c文件宏展开_C宏展开的几个注意事项

前阵子仔细重新研究了一下C的宏展开。总结起来,有以下几个主要规则:

每次宏展开的结果会被重复扫描,直到没有任何可展开的宏为止。

每展开一个宏,都会记住这次展开,在这个宏展开的结果及其后续展开中,不再对相同的宏做展开。

带参数的宏,先对参数做展开,除非宏定义体中包含#或##

a) #表示将后续标识符转换为字符串

b) ##表示将两个标识符连接成一个标识符

c) 注意参数展开的结果中即使有逗号(,),也不视为参数的分隔符

如果宏定义中带有参数,而代码中出现同样标识符时没有参数,不视为宏。

下面的三段代码分别解释了2, 3, 4. 注释中描述了宏每一步展开的细节

这段代码主要解释规则2.(~表示已经被展开过)

#define foo foo bar

#define bar bar bar foo

#define foo2(a) bar2(a,foo2) foo2(a) (a)

#define bar2(a, b) foo2(a) bar2(a,b) (a) (b)

foo

// |-> foo bar

// | |~ |-> bar bar foo

// |-> foo bar bar foo (至此,所有符号都已展开过)

bar

// |-> bar bar foo

// | |~ |~ |-> foo bar

// |-> bar bar foo bar (至此,所有符号都已展开过)

foo bar

// foo bar

// | |

// |-> foo bar bar bar foo

// | |~ | |~ |~ |

// |-> foo bar bar foo bar bar foo bar

foo2(1)

// |-> bar2(1, foo2) foo2(1) (1)

// | | |~

// |-> foo2(1) bar2(1, foo2) (1) (foo2) foo2(1) (1)

bar2(1, 1)

// |-> foo2(1) bar2(1,1) (1) (1)

// | | |~

// |-> bar2(1,foo2) foo2(1) (1) bar2(1,1) (1) (1)

这段代码主要解释规则3.

#define foo vfoo

#define bar vbar

#define foo2(a) #a

#define foo3(a, b) a ## _ ## b

#define foo20(a) foo2(a)

#define foo30(a, b) foo3(a, b)

#define foo40(x) foo30(x)

#define x x1,x2

foo2(foo)

// -> "foo" ('#'阻止了参数展开,如果需要展开参数,定义另一个宏,见foo20)

foo3(foo, bar)

// -> foo_bar ('##'阻止了参数展开,如果需要展开参数,定义另一个宏,见foo30)

foo20(foo)

// | |-->vfoo (foo20带有一个参数,匹配宏定义,先展开参数)

// | |

// |-> foo2(vfoo)

// |-> "vfoo"

foo30(foo, bar)

// | |-->vfoo, |->vbar

// | | |

// |-> foo3(vfoo, vbar)

// |-> vfoo_vbar

foo30(x)

// 错误,参数个数不匹配, x中的逗号不视为参数分隔符。如果需要将这个逗号作为分隔符,定义另一个宏,见foo40

foo40(x)

// | |-> x1,x2

// |-> foo30(x1,x2) //这个时候,逗号视为合法分隔符。

// |-> foo3(x1,x2)

// |-> x1_x2

这段代码主要解释规则4.

#define foo(a) foo=a(x)

#define bar(a) (bar=a)

#define foo2(a) foo=a(x,y)

#define bar2(a,b) bar(a*b)

foo

// 参数个数不匹配,不认为是宏

bar

// 同上

foo(bar)

// |-> foo=bar(x) (bar无参数,不认为是宏)

// |-> foo=(bar=x) (此次扫描,bar符合宏定义)

foo2(bar2)

// |-> foo=bar2(x,y) (bar2无参数,不认为是宏)

// |-> foo=bar(x*y) (此次扫描,bar符合宏定义)

// |-> foo=(bar=x*y)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值