我使代码片段更简单,以解释
print_score
第一个是直观的,并且在几个地方存在各种代码,例如找到最大或最小数字。但是,我想使用该技术使我的代码干净且易于阅读,因此我用一个更短更有意义的名称替换宏中的某些单词。
AFAIK,C预处理器每个编译单元只运行一次,只执行字符串替换,但为什么printf("%d\n", 80);
无法扩展到#define score student_exam_score
#define print_score(student_exam_score) printf("%d\n", score)
#undef score
print_score(80);
// -->
#define score student_exam_score // runs this first
#define print_score(student_exam_score) printf("%d\n", student_exam_score) // changed
#undef score
print_score(80);
// -->
#define score student_exam_score
#define print_score(student_exam_score) printf("%d\n", student_exam_score) // then this
#undef score
printf("%d\n", 80); // changed
?
这是我猜的替换程序:
tennis_window.title = ('Top Ten Tennis')
答案 0 :(得分:3)
这是一个排序问题。首先定义宏,并且score
在使用之前是未定义的。然后,当展开print_score
时,它首先替换student_exam_score
的所有实例,其中没有score
。然后重新扫描结果,寻找进一步扩展的宏,但是由于#undef score
未定义且不再可用,因此没有。
即使您将print_score
移到score
的引用之下,它仍然无效,因为参数替换只发生一次(student_exam_score
会扩展但score
不会)。
请注意,print_score
在定义时未被#undef score
替换为score
。仅在实例化宏时才会进行替换,这就是#define foo bar
#define baz(bar) (foo)
baz(123)
导致 baz(123)
-> (foo)
-> (bar)
宏无效的原因。
这些例子将使它更清晰。首先,请考虑以下事项:
foo
这扩展如下:
#define foo bar
#define baz(bar) (foo)
#undef foo
baz(123)
扩张在这里停止。参数替换是在扩展 baz(123)
-> (foo)
之前完成的,并且不会再次发生。
现在考虑以下事项:
foo
这扩展如下:
baz
由于不再定义MapTapped
,因此扩展会停止。它的早期定义对private void MyMap_MapTapped(Windows.UI.Xaml.Controls.Maps.MapControl sender, Windows.UI.Xaml.Controls.Maps.MapInputEventArgs args)
{
var tappedGeoPosition = args.Location.Position;
//Do something
}
的定义没有影响,因为定义宏时不会发生宏替换。只有当它们被扩展时才会发生。