宏定义的macro到底支持空格不?

倒在四百页 2013-08-10 07:52:08
#define MEAN(x, y) (x + y) / 2  //compiled in code::block
int main (void)
{
printf ("%d\n", MEAN (1, 3)); //print: 2
return 0;
}

书上说宏名字中不允许有空格,但上面这段程序没有任何错误。
是说函数宏支持空格,但对象宏不支持?
...全文
487 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
sensorLike 2013-08-11
  • 打赏
  • 举报
回复
引用 9 楼 u011489259 的回复:
[quote=引用 1 楼 buxiaotanke 的回复:]
#define identifier token-sequence
不带参数的宏,identifier前后的空格都会被丢弃。
#define identifier( identifier-list ) token-sequence
带参数的宏,第一个identifier和'('之间不能有空格,不然就会被解释成第一种。
你这个倒是一针见血。 可否再追问下,函数宏对括号处理的过程是怎么样的? 另外,有没有直观的办法看到宏展开后的c代码?还是只能像目前这样推测?[/quote] 不能说是推测吧。。虽然我也不知道怎么能看到,但是根据标准来写没错的,多测试几下就明白了。。
sensorLike 2013-08-11
  • 打赏
  • 举报
回复
。。按错了,接着上面。 引用一下原文,以防因为英语水平差误导楼主。。。 A preprocessing directive of the form

# define identifier lparen identifier-list_opt ) replacement-list new-line
# define identifier lparen ... ) replacement new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
defines a function-like macro with arguments, similar syntactically to a function call. The parameters are specified by the optional list of identifiers, whose scope extends from their declaration in the identifier list until the new-line character that terminates the #define preprocessing directive. Each subsequent instance of the function-like macro name followed by a ( as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro). The replaced sequence of preprocessing tokens is terminated by the matching ) preprocessing tokens. Within the sequence of preprocessing tokens making up an invocation of a function-like macro, new-line is considered a normal white-space character. ps:抄错或者打错字本人概不负责。。
sensorLike 2013-08-11
  • 打赏
  • 举报
回复
引用 9 楼 u011489259 的回复:
[quote=引用 1 楼 buxiaotanke 的回复:]
#define identifier token-sequence
不带参数的宏,identifier前后的空格都会被丢弃。
#define identifier( identifier-list ) token-sequence
带参数的宏,第一个identifier和'('之间不能有空格,不然就会被解释成第一种。
你这个倒是一针见血。 可否再追问下,函数宏对括号处理的过程是怎么样的? 另外,有没有直观的办法看到宏展开后的c代码?还是只能像目前这样推测?[/quote] <<The C Programming Language>> 2nd Edition When a macro has been defined in the second form(with parameters), subsequent textual instances of the macro identifier followed by optional white space, and then by (, a sequence of tokens separated by commas, and a ) constitute a call of the macro. standard C 98/99 不带参数的宏是object-like macro,带参数的是function-like macro。 宏定义里跟在宏名后面的lparen(左括号)是一个预处理token,引出后面的替换列表,右括号用来结束替换列表,中间插入的成对括号会被忽略。 引用
倒在四百页 2013-08-11
  • 打赏
  • 举报
回复
引用 15 楼 my_live_123 的回复:
[quote=引用 8 楼 u011489259 的回复:] [quote=引用 3 楼 my_live_123 的回复:] 无所谓支持不支持,整体字符串替换。你定义时候,参数有空格,那么使用的时候就需要加上,如果不加就会错误,匹配不了,替换不成。它说的支持不支持,只是说它不会对定义内容中多余空格进行剔除解析,而是整体一股脑子完全匹配方式替换掉
不对吧?我定义时候参数有空格,我使用时候不加也行的。

#define MEAN(x, y) (x + y) / 2
int main (void)
{
	printf ("%d\n",  MEAN (1,3));
	return 0;
}
[/quote] 恩,编译器还是做了点工作[/quote] 编译器干啥了?宏展开不是预处理器干滴吗?
一根烂笔头 2013-08-11
  • 打赏
  • 举报
回复
引用 8 楼 u011489259 的回复:
[quote=引用 3 楼 my_live_123 的回复:] 无所谓支持不支持,整体字符串替换。你定义时候,参数有空格,那么使用的时候就需要加上,如果不加就会错误,匹配不了,替换不成。它说的支持不支持,只是说它不会对定义内容中多余空格进行剔除解析,而是整体一股脑子完全匹配方式替换掉
不对吧?我定义时候参数有空格,我使用时候不加也行的。

#define MEAN(x, y) (x + y) / 2
int main (void)
{
	printf ("%d\n",  MEAN (1,3));
	return 0;
}
[/quote] 恩,编译器还是做了点工作
mujiok2003 2013-08-10
  • 打赏
  • 举报
回复
引用 10 楼 u011489259 的回复:
[quote=引用 6 楼 mujiok2003 的回复:] 最后不加

//compiled in code::block
#define MEAN(x, y) ((x)+(y))/2 
你是想说最好带括号吧?那是个好习惯。[/quote] 最好加上括号,不加空格,lol
倒在四百页 2013-08-10
  • 打赏
  • 举报
回复
引用 6 楼 mujiok2003 的回复:
最后不加

//compiled in code::block
#define MEAN(x, y) ((x)+(y))/2 
你是想说最好带括号吧?那是个好习惯。
倒在四百页 2013-08-10
  • 打赏
  • 举报
回复
引用 1 楼 buxiaotanke 的回复:
#define identifier token-sequence
不带参数的宏,identifier前后的空格都会被丢弃。
#define identifier( identifier-list ) token-sequence
带参数的宏,第一个identifier和'('之间不能有空格,不然就会被解释成第一种。
你这个倒是一针见血。 可否再追问下,函数宏对括号处理的过程是怎么样的? 另外,有没有直观的办法看到宏展开后的c代码?还是只能像目前这样推测?
倒在四百页 2013-08-10
  • 打赏
  • 举报
回复
引用 3 楼 my_live_123 的回复:
无所谓支持不支持,整体字符串替换。你定义时候,参数有空格,那么使用的时候就需要加上,如果不加就会错误,匹配不了,替换不成。它说的支持不支持,只是说它不会对定义内容中多余空格进行剔除解析,而是整体一股脑子完全匹配方式替换掉
不对吧?我定义时候参数有空格,我使用时候不加也行的。

#define MEAN(x, y) (x + y) / 2
int main (void)
{
	printf ("%d\n",  MEAN (1,3));
	return 0;
}
mujiok2003 2013-08-10
  • 打赏
  • 举报
回复
引用 6 楼 mujiok2003 的回复:
最后不加

//compiled in code::block
#define MEAN(x, y) ((x)+(y))/2 
最后->最好
mujiok2003 2013-08-10
  • 打赏
  • 举报
回复
最后不加

//compiled in code::block
#define MEAN(x, y) ((x)+(y))/2 
mujiok2003 2013-08-10
  • 打赏
  • 举报
回复
预处理后

int main (void)
{
	printf ("%d\n", (1 + 3) / 2);  
	return 0;
}
VC选项: /P
max_min_ 2013-08-10
  • 打赏
  • 举报
回复
引用 楼主 u011489259 的回复:
#define MEAN(x, y) (x + y) / 2  //compiled in code::block
int main (void)
{
	printf ("%d\n", MEAN (1, 3));  //print: 2
	return 0;
}
书上说宏名字中不允许有空格,但上面这段程序没有任何错误。 是说函数宏支持空格,但对象宏不支持?
宏只会作等价替换, 不会做任何安全检查操作的!
AnYidan 2013-08-10
  • 打赏
  • 举报
回复
理解就行了!
sensorLike 2013-08-10
  • 打赏
  • 举报
回复
#define identifier token-sequence
不带参数的宏,identifier前后的空格都会被丢弃。
#define identifier( identifier-list ) token-sequence
带参数的宏,第一个identifier和'('之间不能有空格,不然就会被解释成第一种。
一根烂笔头 2013-08-10
  • 打赏
  • 举报
回复
无所谓支持不支持,整体字符串替换。你定义时候,参数有空格,那么使用的时候就需要加上,如果不加就会错误,匹配不了,替换不成。它说的支持不支持,只是说它不会对定义内容中多余空格进行剔除解析,而是整体一股脑子完全匹配方式替换掉

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧