通过#define 预处理器指令覆盖 C++ 中的“endl”
Posted
技术标签:
【中文标题】通过#define 预处理器指令覆盖 C++ 中的“endl”【英文标题】:Overriding "endl" in C++ by #define preprocessor directive 【发布时间】:2016-02-19 02:37:46 【问题描述】:我使用以下代码覆盖endl
并将其替换为“新行”以外的其他内容。
#include <iostream>
#include <string>
using namespace std;
#define endl "OOOO" //replacing "endl"
int main()
cout << "start " << endl << " end";
return 0;
那么结果会是:
start OOOO end
代替:
start
end
但对cout
执行相同操作会导致错误。
为什么我们可以对endl
这样做,但我们不能对cout
这样做?
【问题讨论】:
如果您尝试将cout
或printf
定义为其他内容会怎样? (老实说,你不应该这样做。)
CPP,在某种形式下,“总是”首先运行。查看 that 结果以解决问题。例如,在 gcc 中,使用 -E flag.
为什么你认为你不能用cout
或printf
做同样的事情?
当我定义'cout'和'printf'时,只要我不在程序中使用它们我很好,但是当它们在程序主体中使用时会出错调试。
请编辑您的帖子并澄清您看到的差异,最好使用正确示例代码和完整错误。
【参考方案1】:
为什么我可以写一个#define
宏来代替endl
?
因为你可以为任何东西编写一个#define
宏。 #define
宏是在预处理步骤中运行的简单搜索和替换。
为什么我不能写一个#define
宏来替换cout
或printf
?
你可以。你可以为任何东西编写一个#define
宏。
但是当我为 cout
和 printf
编写 #define
宏时,我的代码无法编译。
发生这种情况是因为发生宏扩展后,会出现编译错误。
【讨论】:
【参考方案2】:这当然取决于您将宏定义为什么以及如何使用它。预处理后,如下:
#define endl "OOOO"
cout << "start " << endl << " end";
变成这样:
cout << "start " << "OOOO" << " end";
这是一个完全有效的陈述。但是,经过预处理后:
#define cout "OOOO"
cout << "start " << endl << " end";
变成这样:
"OOOO" << "start " << endl << " end";
这不是一个有效的陈述。如果你这样做:
#define printf "OOOO"
cout << printf;
变成这样:
cout << "OOOO";
这很好。同样,如果您这样做:
#define cout "OOOO"
printf(cout);
变成这样:
printf("OOOO");
这也很好。
【讨论】:
【参考方案3】:你搞砸了编译过程的两个部分。
第一个,解析#define
是预处理器和简单的文本替换。它不关心你替换了什么,也不知道任何关键字。
第二部分是编译本身,其中关键字被实际解释并赋予一些“意义”。
在您的示例中,行
cout << "start " << endl << " end";
变成
cout << "start " << "OOOO" << " end";
这是完全有效的。如果您尝试使用 cout 进行类似的操作,您可能会得到一些无效的结果。
要弄得更乱,你可以这样做:
#define printf cout
#define if while
#define void int
#define delete(x) x++
int main()
void i=0;
if(i<5)
printf << i << endl;
delete(i);
return 0;
会变成
int main()
int i=0;
while(i<5)
cout<< i << endl;
i++;
return 0;
在被编译器处理之前。
Try it online
但是,您永远不应该使用宏来更改众所周知的关键字或标准库的某些部分的行为。它会使代码不可读、维护混乱并且可能会破坏东西。
【讨论】:
以上是关于通过#define 预处理器指令覆盖 C++ 中的“endl”的主要内容,如果未能解决你的问题,请参考以下文章
#define 预处理器指令可以包含 if 和 else 吗?