C 使用两个参数重载宏
我有一堆定义,它们看起来都像这样定义D,0,它们包含一个a-D的字母和一个0-8的数字,用逗号分隔 现在我正在尝试创建一个宏,如:,但这将适用于我的案例。这个站点上的宏只适用于一个带有一个参数的#define,而我的有两个参数 这就是我目前拥有的:C 使用两个参数重载宏,c,macros,C,Macros,我有一堆定义,它们看起来都像这样定义D,0,它们包含一个a-D的字母和一个0-8的数字,用逗号分隔 现在我正在尝试创建一个宏,如:,但这将适用于我的案例。这个站点上的宏只适用于一个带有一个参数的#define,而我的有两个参数 这就是我目前拥有的: #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME #define TEST_MACRO(...) GET_MACRO(__VA_ARGS__, _TEST_MA
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME
#define TEST_MACRO(...) GET_MACRO(__VA_ARGS__, _TEST_MACRO_8, _TEST_MACRO_7, _TEST_MACRO_6, _TEST_MACRO_5, _TEST_MACRO_4, _TEST_MACRO_3, _TEST_MACRO_2, _TEST_MACRO_1) (__VA_ARGS__)
#define _TEST_MACRO_8(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6, letter7, number7, letter8, number8) (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) | (1 << number8))
#define _TEST_MACRO_7(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6, letter7, number7) (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7))
#define _TEST_MACRO_6(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6) (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6))
#define _TEST_MACRO_5(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5) (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5))
#define _TEST_MACRO_4(letter1, number1, letter2, number2, letter3, number3, letter4, number4) (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4))
#define _TEST_MACRO_3(letter1, number1, letter2, number2, letter3, number3) (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3))
#define _TEST_MACRO_2(letter1, number1, letter2, number2) (PORT##letter1 |= ((1 << number1) | (1 << number2))
#define _TEST_MACRO_1(letter1, number1) (PORT##letter1 |= (1 << number1))
这里有什么问题?我怎样才能解决它
致以最良好的祝愿
编辑:
为了澄清一点,这里是这个应用的背景。我正在编程一个8位AVR微控制器。我知道我有这样定义的管脚:#定义管脚1 A,0
,其中A表示管脚字母,0表示管脚编号
如果我用这种方式定义了一大堆,当我想更改其中的一些设置时,我必须一个接一个地手动执行,就像这样:pinu HIGH(PIN1);引脚_高(引脚2);PIN_高(PIN3)
,而且它们越多,代码就会变得非常混乱
因此,我正在寻找一种使用一个宏的方法:pinu高(PIN1、PIN2、PIN3)代码>。当我将PIN1、PIN2、PIN3
字母传递给宏时,它们的匹配也很重要,因为有时,我可以将pin移动到其他字母
任何关于如何做到这一点的建议都是非常受欢迎的 宏ONE
、TWO
和TWO
在展开TEST\u MACRO
之前都会立即展开,因此当您说TEST\u MACRO(ONE)
时,的VA\u ARGS\uuu
宏arg设置为D,0
(一个的展开),这意味着您调用\u TEST\u MACRO\u2
,因为这是两个论点
由于始终需要偶数个参数,因此可以将TEST\u宏
定义为:
#define TEST_MACRO(...) GET_MACRO(__VA_ARGS__, _TEST_MACRO_4, ERROR, _TEST_MACRO_3, ERROR, _TEST_MACRO_2, ERROR, _TEST_MACRO_1, ERROR) (__VA_ARGS__)
#define ERROR(...) #error "Odd number of arguments to TEST_MACRO"
除第一个字符外,不使用表示端口的字符。所以,我建议采用以下方法
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME
#define TEST_MACRO(letter,...) (PORT##letter |= GET_MACRO(__VA_ARGS__, _TEST_MACRO_8, _TEST_MACRO_7, _TEST_MACRO_6, _TEST_MACRO_5, _TEST_MACRO_4, _TEST_MACRO_3, _TEST_MACRO_2, _TEST_MACRO_1) (__VA_ARGS__) )
#define _TEST_MACRO_8(number1, number2, number3, number4, number5, number6, number7, number8) \
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) | (1 << number8)
#define _TEST_MACRO_7(number1, number2, number3, number4, number5, number6, number7)\
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7)
#define _TEST_MACRO_6(number1, number2, number3, number4, number5, number6)\
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6)
#define _TEST_MACRO_5(number1, number2, number3, number4, number5)\
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5)
#define _TEST_MACRO_4(number1, number2, number3, number4)\
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4)
#define _TEST_MACRO_3(number1, number2, number3)\
(1 << number1) | (1 << number2) | (1 << number3)
#define _TEST_MACRO_2(number1, number2)\
(1 << number1) | (1 << number2)
#define _TEST_MACRO_1(number1)\
(1 << number1)
TEST_MACRO(D, 1);
TEST_MACRO(D, 0, 1);
TEST_MACRO(D, 0, 1, 2);
#define ONE (D, 0)
#define TWO (D, 1)
#define THREE (D, 2)
#define CAR(a,b) a
#define CDR(a,b) b
#define F(x) CAR x
#define R(x) CDR x
#define TEST_MACRO_WRAP(...) TEST_MACRO(__VA_ARGS__)
TEST_MACRO_WRAP(F(ONE), R(ONE));
TEST_MACRO_WRAP(F(ONE), R(ONE), R(TWO));
TEST_MACRO_WRAP(F(ONE), R(ONE), R(TWO), R(THREE));
#定义GET_宏(_1,_2,_3,_4,_5,_6,_7,_8,NAME,…)名称
#定义测试宏(字母…)(端口##字母|=获取宏
#定义测试宏(数字1、数字2、数字3、数字4、数字5、数字6、数字7、数字8)\
(1)我想不出比这更好的方法了……任何改进都非常受欢迎!它更容易阅读:引脚高(引脚1、引脚2、引脚8);而不是端口((1我相信你可以比你的第二个例子做得更清楚,几乎任何事情都比猜测哪一个宏实际被扩展要好。但正如我所说,我不会是使用它的人,所以很明显这是你的决定。不过,你问过了。:-)\define D,0
是定义宏的一种奇怪的方式。宏名是D
,而,
是扩展的第一个标记。为什么不插入一个空格呢?\define D,0
很抱歉,这是一个打字错误。我的意思是#define PIN D,0我将在明天试用,并让你知道。因为我住的地方已经很晚了。我非常喜欢t他的,但是有没有一种方法可以传递整个一、二、三定义,而不必传递其中的一部分,比如一的字母和数字,然后只传递二的数字。然后,是否可以在宏中检查传递的所有字母是否相同,如果不相同,则抛出一个#错误?谢谢!这个检查是否所有字母都相同必须是正确的在编译时完成,因为我可用的资源非常有限。再次感谢!@user1806687在预处理器中无法比较非数字的相等性。我不知道这是否有任何区别,但字母是枚举的一部分:typedef enum PIN_字母{A,B,C,D}letters_t;@user1806687您不能直接使用在预处理器中的C程序中定义的类型或变量。可以嵌入代码,但如果需要,可以将其定义为函数。也不能进行编译时检查。
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME
#define TEST_MACRO(letter,...) (PORT##letter |= GET_MACRO(__VA_ARGS__, _TEST_MACRO_8, _TEST_MACRO_7, _TEST_MACRO_6, _TEST_MACRO_5, _TEST_MACRO_4, _TEST_MACRO_3, _TEST_MACRO_2, _TEST_MACRO_1) (__VA_ARGS__) )
#define _TEST_MACRO_8(number1, number2, number3, number4, number5, number6, number7, number8) \
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) | (1 << number8)
#define _TEST_MACRO_7(number1, number2, number3, number4, number5, number6, number7)\
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7)
#define _TEST_MACRO_6(number1, number2, number3, number4, number5, number6)\
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6)
#define _TEST_MACRO_5(number1, number2, number3, number4, number5)\
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5)
#define _TEST_MACRO_4(number1, number2, number3, number4)\
(1 << number1) | (1 << number2) | (1 << number3) | (1 << number4)
#define _TEST_MACRO_3(number1, number2, number3)\
(1 << number1) | (1 << number2) | (1 << number3)
#define _TEST_MACRO_2(number1, number2)\
(1 << number1) | (1 << number2)
#define _TEST_MACRO_1(number1)\
(1 << number1)
TEST_MACRO(D, 1);
TEST_MACRO(D, 0, 1);
TEST_MACRO(D, 0, 1, 2);
#define ONE (D, 0)
#define TWO (D, 1)
#define THREE (D, 2)
#define CAR(a,b) a
#define CDR(a,b) b
#define F(x) CAR x
#define R(x) CDR x
#define TEST_MACRO_WRAP(...) TEST_MACRO(__VA_ARGS__)
TEST_MACRO_WRAP(F(ONE), R(ONE));
TEST_MACRO_WRAP(F(ONE), R(ONE), R(TWO));
TEST_MACRO_WRAP(F(ONE), R(ONE), R(TWO), R(THREE));