5

我对 C++ 比较陌生,我正在学习它。我们班被分配了一个实验室,我的老师说实验室的文章有点难以理解;然而,他并没有对实验室的文章做任何修改。所以,我遇到了实验室的这一部分:

定义预处理器宏

长期以来的约定是宏名大写,这个宏名必须是TRACE_FUNC。宏有一个参数,当您将宏应用于代码时,该参数将被函数名替换。宏的开头如下所示:

#define TRACE_FUNC( symbol )  replacement-text`

并且预处理器将在源代码中存在 TRACE_FUNC(sym) 字符串的任何地方替换替换文本,并将符号输入到该替换中。

注意:#define 语句必须全部位于单个逻辑行上。为了保持长度可控,您可以在行尾使用反斜杠转义换行符;这将使预处理器保持满意,同时允许您跨越多行定义。

对于本练习,替换文本必须是完整的语句,包括终止分号。

替换文本必须是输出语句,该语句打印符号后跟调用的文本 ()。和标准输出的换行符。您可以从 warning.cpp 源文件复制和修改其中一个输出语句。

warning.cpp只是我们正在使用的一个文件,TRACE_FUNC它被放置在一个头文件中。

所以,我读了几次,我不是 100% 确定它在问什么。从某种角度来看,它似乎要求我创建一个名为 TRACE_FUNC 的宏。如果换个角度看,它要求我使用宏 TRACE_FUNC。所有这些都很好,但我根本不知道如何使用 TRACE_FUNC,我在任何地方都找不到任何文档,也不知道如何创建宏。当我寻求帮助时,我的老师只是说。单词而不是那些非常有用的单词,因为它是一个非常曲折、令人困惑的答案,没有解释 TRACE_FUNC 实际上是什么。

基本上,我的老师所说的只是其中的符号TRACE_FUNC需要是源代码中的一个函数的名称。例如,假设我们foo()在警告中有一个函数,那么根据他的解释,该符号应该是foo()(或 foo,我也不确定)。此外,在替换文本中,如果我将名称放在#符号前面,显然名称本身将被替换。我认为这应该表示预处理器指令。为什么我应该在这里使用它?

无论如何,照我老师说的做几乎没有任何用处。这条线也没有

#define TRACE_FUNC( foo() ) #foo() called. ;

也不是这条线

#define TRACE_FUNC( foo ) #foo () called. ;

替换任何文本,我很确定这是#define 指令的操作。所以我一定是以错误的方式应用我的老师所说的,但我真的不知道为什么它是错误的或如何解决它。

所以,我的问题。实际上是TRACE_FUNC一个宏,如果是,是否有任何我可以阅读的文档?或者我应该创造TRACE_FUNC,如果是这样,我应该怎么做?

4

2 回答 2

6

哇,真垃圾!您应该正确学习 C++,而不是复杂的预处理器。

这就是你应该做的事情,但为什么有人猜测。

#define TRACE_FUNC(sym) std::cout << #sym << "() called\n"

void foo()
{
  TRACE_FUNC(foo);
  ...
}

我假设有来自warning.cpp的示例,std::cout如果没有使用,那么您必须将上述内容调整为您在warning.cpp中找到的任何内容。

这个想法是每个函数都从使用 TRACE_FUNC 宏开始,因此您可以跟踪代码的执行。为什么教授认为这对新手来说是个好主意,这超出了我的理解。即使这是一个好主意,但期望你自己弄清楚细节是更愚蠢的。

我可以改进上面的宏,但这可能会更加混乱,所以我不会。现在我只会照教授说的去做,但忽略它。希望他以后能学到一些值得学习的东西。

于 2012-09-08T14:16:01.330 回答
-1

这是一个示例:在您的库中使用输出打印功能来替换此处的标准功能 printf

 #define TRACE_FUNC(sym) printf("%s() called", #sym);

将其用作

TRACE_FUNC(printf)

输出应该是

printf() called

您的实际任务是以定义的格式打印出一个符号。所以你需要在你的#define 中使用 printf 或类似的函数。

于 2012-09-08T14:24:28.350 回答