通过#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 这样做?

【问题讨论】:

如果您尝试将coutprintf 定义为其他内容会怎样? (老实说,你不应该这样做。) CPP,在某种形式下,“总是”首先运行。查看 that 结果以解决问题。例如,在 gcc 中,使用 -E flag. 为什么你认为你不能用coutprintf做同样的事情? 当我定义'cout'和'printf'时,只要我不在程序中使用它们我很好,但是当它们在程序主体中使用时会出错调试。 请编辑您的帖子并澄清您看到的差异,最好使用正确示例代码和完整错误。 【参考方案1】:

为什么我可以写一个#define宏来代替endl

因为你可以为任何东西编写一个#define 宏。 #define 宏是在预处理步骤中运行的简单搜索和替换。

为什么我不能写一个#define 宏来替换coutprintf

你可以。你可以为任何东西编写一个#define 宏。

但是当我为 coutprintf 编写 #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 特定于我的机器

预指令

小白学习C++ 教程十四C++ 中预处理器

#define 预处理器指令可以包含 if 和 else 吗?

在 C# 的 #if 中使用 #define 预处理器指令是不是有效

C#预处理器指令之#define/#undefine/#if/#elif/#else/#endif