编写C宏时,有一个叫做“序列迭代”的技巧。它看起来如下:
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define FUNCTION(name) void name();
#define FUNCTION_TABLE(seq) CAT(FUNCTION_TABLE_1 seq, _END)
#define FUNCTION_TABLE_1(x) FUNCTION(x) FUNCTION_TABLE_2
#define FUNCTION_TABLE_2(x) FUNCTION(x) FUNCTION_TABLE_1
#define FUNCTION_TABLE_1_END
#define FUNCTION_TABLE_2_END
FUNCTION_TABLE((x) (y) (z) (e))
序列,即FUCTION_TABLE的参数,将逐一处理。但是,据我所知,令牌不会在同一范围内扩展两次。因为它是“涂成蓝色”。展开FUNCTION_TABLE_2时,宏FUNCTION_TABLE_1已经绘制好了。它为什么还在扩展?
答案 0 :(得分:2)
类似函数的宏替换是一个递归过程:
#
和##
#
或##
的操作数的令牌被扩展#
和##
(如果有)应用于生成的操作数(这比描述更复杂!)。所以对于你的代码:
FUNCTION_TABLE((x) (y) (z) (e))
扩展为CAT(FUNCTION_TABLE_1 (x) (y) (z) (e), _END)
CAT(X, _END)
扩展为PRIMITIVE_CAT(expand(X), _END)
。立即制定expand(X)
:
FUNCTION_TABLE_1 (x) (y) (z) (e)
扩展为FUNCTION(x) FUNCTION_TABLE_2 (y) (z) (e)
:
FUNCTION(x)
扩展为void x();
FUNCTION_TABLE_2 (y) (z) (e)
扩展为FUNCTION(y) FUNCTION_TABLE_1 (z) (e)
FUNCTION(y)
扩展为void y();
FUNCTION_TABLE_1 (z) (e)
扩展为FUNCTION(z) FUNCTION_TABLE_2(e)
FUNCTION(z)
扩展为void z();
FUNCTION_TABLE_2(e)
扩展为FUNCTION(e) FUNCTION_TABLE_1
FUNCTION(e)
扩展为void e();
void e(); FUNCTION_TABLE_1
void z(); void e(); FUNCTION_TABLE_1
void y(); void z(); void e(); FUNCTION_TABLE_1
void x(); void y(); void z(); void e(); FUNCTION_TABLE_1
X
后,让我们回顾一下我们所处的位置:PRIMITIVE_CAT(void x(); void y(); void z(); void e(); FUNCTION_TABLE_1, _END)
void x(); void y(); void z(); void e(); FUNCTION_TABLE_1_END
void x(); void y(); void z(); void e();
答案 1 :(得分:1)
这个想法是在宏扩展中,参数的所有扩展都将以相同的BLUE-SET开始。
在driver.findElement(By.id("divImgAnnualAllowanceType")).getAttribute("value");
内,FUNCTION_TABLE(seq)
内所有参数的扩展将始终以BLUE-SET = {seq}开始。因此,在输入FUNCTION_TABLE_1后,BLUE-SET被添加到FUNCTION_TABLE_1 seq
,但是当这完成后,它将回到x
的范围,再次使用FUNCTION_TABLE
开始扩展。
因此,第一次展开BLUE-SET={seq}
并在FUNCTION_TABLE_1(x)
展开此展开,但当BLUE-SET={seq,x}
的展开完成时,它会回到FUNCTION_TABLE_1
,它会然后再展开此范围FUNCTION_TABLE
和INSIDE FUNCTION_TABLE_2(y)
BLUE-SET = {seq,x}等等。