C预处理器如何实际工作?

时间:2016-05-15 08:29:42

标签: c macros

我使代码片段更简单,以解释

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')

1 个答案:

答案 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 } 的定义没有影响,因为定义宏时不会发生宏替换。只有当它们被扩展时才会发生。