我们可以来看看有调试句子的程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

int getUserInput()
{
std::cerr << "getUserInput() called\n";
std::cout << "Enter a number: ";
int x{};
std::cin >> x;
return x;
}

int main()
{
std::cerr << "main() called\n";
int x{ getUserInput() };
std::cout << "You entered: " << x << '\n';

return 0;
}

完成调试语句后,您需要将其删除或注释掉。然后,如果您稍后再次需要它们,则必须将它们添加回来,或取消注释它们。

这样很麻烦,有一个up的办法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

#define ENABLE_DEBUG // comment out to disable debugging

int getUserInput()
{
#ifdef ENABLE_DEBUG
std::cerr << "getUserInput() called\n";
#endif
std::cout << "Enter a number: ";
int x{};
std::cin >> x;
return x;
}

int main()
{
#ifdef ENABLE_DEBUG
std::cerr << "main() called\n";
#endif
int x{ getUserInput() };
std::cout << "You entered: " << x << '\n';

return 0;
}

#ifdef ENABLE_DEBUG 如果定义了ENABLE_DEBUG就执行下面的句子

但是:代价是代码更加混乱

这里我们可以看到:std::cerr 这个句子的意思大致和std::cout差不多。

反正就是说:如果错误的话就使用std::cerr

1
cout对应于标准输出流,默认情况下是显示器。 这是一个被缓冲的输出,可以被重定向。 cerr对应标准错误流,用于显示错误消息。 默认情况下被关联到标准输出流,但它不被缓冲,也就说错误消息可以直接发送到显示器,而无需等到缓冲区或者新的换行符时,才被显示。

Using a logger 使用记录器

在较大或对性能敏感的项目中,可能会首选速度更快且功能更丰富的记录器,例如 spdlog。

在 Visual Studio 中,可以通过“调试”菜单 >“逐语句”或按 F11 快捷键来访问单步执行命令。

  • 进函数

在 Visual Studio 中,可以通过“调试”菜单 >“逐过程”或按 F10 快捷键来访问单步执行命令。

  • 不进函数

在 Visual Studio 中,可以通过“调试”菜单 >“步出”或按 Shift-F11 快捷组合来访问步出命令。

12

从下往上看:main()函数调用了b()函数,b()函数调用了a()函数。