C 为什么这些宏定义的展开方式如此不同?

C 为什么这些宏定义的展开方式如此不同?,c,macros,C,Macros,对于C语言INC1和INC3中的上述声明,效果很好,但INC2和INC4给出了错误,为什么 参考:第一个问题类似函数的宏的语法要求在宏名称后面紧跟着左括号,中间没有空格 预处理器使用宏名称后的空格推断宏名称何时结束,宏主体何时开始 例如: #define INC1(a) ((a)+1) #define INC2 (a) ((a)+1) #define INC3( a ) (( a ) + 1) #define INC4 ( a ) (( a ) + 1) 这定义了一个非函数类宏,该宏扩展

对于C语言INC1和INC3中的上述声明,效果很好,但INC2和INC4给出了错误,为什么


参考:第一个问题

类似函数的宏的语法要求在宏名称后面紧跟着左括号,中间没有空格

预处理器使用宏名称后的空格推断宏名称何时结束,宏主体何时开始

例如:

#define INC1(a) ((a)+1)

#define INC2 (a) ((a)+1)

#define INC3( a ) (( a ) + 1)

#define INC4 ( a ) (( a ) + 1)

这定义了一个非函数类宏,该宏扩展为
(a)((a)+1)

函数类宏的语法要求在宏名称后面紧跟着左括号,中间没有空格

预处理器使用宏名称后的空格推断宏名称何时结束,宏主体何时开始

例如:

#define INC1(a) ((a)+1)

#define INC2 (a) ((a)+1)

#define INC3( a ) (( a ) + 1)

#define INC4 ( a ) (( a ) + 1)

这定义了一个类似于宏的非函数,它扩展为
(a)((a)+1)

请将此作为一些程序员的答案的扩展示例

根据您的定义,这段代码

#define INC2 (a) ((a)+1)
将扩展到

INC1(10)
INC2(20)
INC3(30)
INC4(40)
我想现在的问题是“为什么空白的存在如此重要?”
格罗的评论中以一种深刻的方式暗示了这个问题的答案(我希望他们允许我在这里使用和阐述)

假设您确实希望将宏扩展为类似于
(a)((a)+1)
。如果这两个定义被一视同仁,你会怎么做

((10)+1)
(a) ((a)+1)(20)
(( 30 ) + 1)
( a ) (( a ) + 1)(40)
并将扩大到

#define INC1(a) ((a)+1)
#define INC2 (a) ((a)+1)
两者的区别

((10)+1)
((20)+1)

以一种直观的方式使之成为可能。一旦你意识到这个问题。

请将此作为某个程序员的答案的扩展示例

根据您的定义,这段代码

#define INC2 (a) ((a)+1)
将扩展到

INC1(10)
INC2(20)
INC3(30)
INC4(40)
我想现在的问题是“为什么空白的存在如此重要?”
格罗的评论中以一种深刻的方式暗示了这个问题的答案(我希望他们允许我在这里使用和阐述)

假设您确实希望将宏扩展为类似于
(a)((a)+1)
。如果这两个定义被一视同仁,你会怎么做

((10)+1)
(a) ((a)+1)(20)
(( 30 ) + 1)
( a ) (( a ) + 1)(40)
并将扩大到

#define INC1(a) ((a)+1)
#define INC2 (a) ((a)+1)
两者的区别

((10)+1)
((20)+1)

以一种直观的方式使之成为可能。一旦你意识到了这个问题。

如果你想将
INC2
扩展到
(a)((a)+1)
,你会如何定义它?@Groo这是一种有见地的方法,可以回答隐含的“为什么这样定义?”你会用它来回答吗?或者允许其他人在他们的答案中加入这一点(这将是一个很好的补充,例如一些人的答案。)“但是INC2和INC4给出了错误”我想我知道你的意思,但这是猜测。您是否想在一个示例中演示错误。也许看看我的答案中使用的示例,解释一下您的期望以及它是如何导致错误的(可能与一些上下文代码结合在一起)。这只是语法的用法,没有什么令人兴奋的地方。类似于宏的函数的语法是
#define
identifier lparen,其中“identifier”是宏名称,“lparen”定义为:“a
字符前面不立即加空格”尝试查看预处理器的输出(例如
gcc-E…
)如果您想将
INC2
扩展到
(a)((a)+1)
,您会如何定义它?@Groo这是一种有见地的方法,可以回答隐含的“为什么这样定义?”您会用它来回答吗?或者允许其他人将其集成到他们的答案中(这将是对某些人的答案的一个很好的补充)“但是INC2和INC4给出了错误”我想我知道你的意思,但这是猜测。你想在a中演示错误吗。也许看看我的答案中使用的示例,解释一下你的预期以及它是如何导致错误的(可能结合一些上下文代码)。语法就是这样,一点也不令人兴奋。像宏这样的函数的语法是
#define
标识符lparen,其中“identifier”是宏名称,“lparen”定义为:“a
字符前面不带空格”请尝试查看预处理器的输出(例如,
gcc-E…
),如果像
INC2(5)
那样使用,它将扩展到
(a)((a)+1)(5)
,不是吗?@Yunnosch是的,它应该。如果像
INC2(5)
那样使用,它将扩展到
(a)((a)+1)(5)
,不是吗?@Yunnosch是的,它应该。