6

我假设大多数 C++ 编译器都是用汇编语言编写的。这使它们完全不同的语言(我可能是错的)。话虽如此,如果我要cout为普通的旧 C 创建一个样式函数,我会怎么做呢?cout有一些非常令人印象深刻的功能,以这个片段为例:

// endl not only prints a new line but also flushes the stream
cout << "Hello World!" << endl;

我很确定在 C 中可以翻译为:

printf("Hello World!\n");
fflush(1);                  //stdout = 1

下一个业务顺序,<<运营商。在 C++ 中,这很容易(运算符重载),但我想不出在 C 中执行此操作的单一方法。

4

3 回答 3

8

在“<<”运算符语法和“operator<<”函数语法之间进行转换可能有助于考虑这一点。您的 C++ 示例相当于这段 C++ 代码:

operator<< ( operator<< (cout, "Hello World!"), endl);

您应该在这里注意到的第一件事是 cout 实际上并没有很多聪明之处。聪明的是 operator<< 函数——特别是 operator<< 函数的版本,它接受一个流对象(cout 是什么,但许多其他的东西也是)作为它的第一个参数。或者,更准确地说,一系列 operator<< 函数将流对象作为第一个参数,并将特定事物作为第二个参数——每种类型的对象都有一个可以放入 cout 流中。您也可以在该语法中看到 C++ 技巧之一;流对象上的 operator<< 函数总是返回给定它们的流对象,从而允许这种性质的链接。

为了将 C++ 代码放入需要类似 C 函数语法的链接器和系统 ABI 中,大多数 C++ 编译器“修改”函数名称,以便在其中编码它们具有的参数类型。(当然,“<<”不是一个有效的类 C 函数名。)因此,如果您查看为该函数位生成的程序集,您会发现这两个函数的名称是彼此不同——它们会有表示参数类型的后缀。您可以手动执行类似的操作:

operator_lshift__stream__endl(
  operator_lshift__stream__string(cout, "Hello World!"), endl);

你已经有了可以在 C 中实现的东西。

于 2009-08-10T05:29:06.697 回答
5

没错,因为C没有运算符重载,你不能改变<<运算符的行为,它总是会做位移,所以没有办法用它在C++中的精确语义来写'cout',在C。

出于兴趣,g++(GNU C++ 编译器)主要是用 C 编写的。

于 2009-08-10T04:40:56.573 回答
4

C 实际上是 C++ 编译器和标准库的流行实现语言(实际上 C++ 本身也是如此——这个概念有时被称为自托管或引导语言),您可以研究丰富、复杂的 C++ 标准的全部来源库(加上扩展)在这里(抱歉,这是 gcc 3 - 找不到可以在线轻松浏览的 gcc 4 源代码树,当然您可以轻松下载这些源代码并在本地计算机上研究它们)。

就个人而言,我建议从一本好书开始,比如本书——一旦你很好地掌握了 C++ iostreams 的所有晦涩的角落和缝隙(作为奖励,这本书还带你参观了当地的导游——抓住你的帽子!-)。

于 2009-08-10T04:49:55.590 回答