C 使用两个参数重载宏

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

我有一堆定义,它们看起来都像这样定义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_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));