printf()和cout在c++中的区别是什么?
当前回答
对于原语,使用哪个原语可能并不重要。当你想输出复杂的对象时它才有用。
例如,如果你有一门课,
#include <iostream>
#include <cstdlib>
using namespace std;
class Something
{
public:
Something(int x, int y, int z) : a(x), b(y), c(z) { }
int a;
int b;
int c;
friend ostream& operator<<(ostream&, const Something&);
};
ostream& operator<<(ostream& o, const Something& s)
{
o << s.a << ", " << s.b << ", " << s.c;
return o;
}
int main(void)
{
Something s(3, 2, 1);
// output with printf
printf("%i, %i, %i\n", s.a, s.b, s.c);
// output with cout
cout << s << endl;
return 0;
}
现在,上面的内容可能看起来并不是很好,但是让我们假设您必须在代码中的多个地方输出这些内容。不仅如此,假设您添加了一个字段“int d”。使用cout,您只需要在一个地方更改它。然而,使用printf,你可能需要在很多地方改变它,不仅如此,你还需要提醒自己输出哪些。
尽管如此,使用cout,您可以减少大量用于维护代码的时间,不仅如此,如果您在新应用程序中重用对象“Something”,您实际上不必担心输出。
其他回答
Printf是一个函数而cout是一个变量。
我引用一下:
在高层术语中,主要的区别是类型安全(cstdio 没有它),性能(大多数iostreams实现都有 比cstdio慢)和可扩展性(iostreams允许 自定义输出目标和用户定义类型的无缝输出)。
人们经常声称printf要快得多。这在很大程度上是一个神话。我刚刚测试了一下,结果如下:
cout with only endl 1461.310252 ms
cout with only '\n' 343.080217 ms
printf with only '\n' 90.295948 ms
cout with string constant and endl 1892.975381 ms
cout with string constant and '\n' 416.123446 ms
printf with string constant and '\n' 472.073070 ms
cout with some stuff and endl 3496.489748 ms
cout with some stuff and '\n' 2638.272046 ms
printf with some stuff and '\n' 2520.318314 ms
结论:如果你只想要换行,使用printf;否则,cout几乎一样快,甚至更快。更多细节可以在我的博客上找到。
需要澄清的是,我并不是说iostreams总是比printf更好;我只是想说,你应该根据真实的数据做出明智的决定,而不是基于一些常见的、误导性的假设而胡乱猜测。
更新:这里是我用于测试的完整代码。使用g++编译,没有任何其他选项(除了用于计时的-lrt)。
#include <stdio.h>
#include <iostream>
#include <ctime>
class TimedSection {
char const *d_name;
timespec d_start;
public:
TimedSection(char const *name) :
d_name(name)
{
clock_gettime(CLOCK_REALTIME, &d_start);
}
~TimedSection() {
timespec end;
clock_gettime(CLOCK_REALTIME, &end);
double duration = 1e3 * (end.tv_sec - d_start.tv_sec) +
1e-6 * (end.tv_nsec - d_start.tv_nsec);
std::cerr << d_name << '\t' << std::fixed << duration << " ms\n";
}
};
int main() {
const int iters = 10000000;
char const *text = "01234567890123456789";
{
TimedSection s("cout with only endl");
for (int i = 0; i < iters; ++i)
std::cout << std::endl;
}
{
TimedSection s("cout with only '\\n'");
for (int i = 0; i < iters; ++i)
std::cout << '\n';
}
{
TimedSection s("printf with only '\\n'");
for (int i = 0; i < iters; ++i)
printf("\n");
}
{
TimedSection s("cout with string constant and endl");
for (int i = 0; i < iters; ++i)
std::cout << "01234567890123456789" << std::endl;
}
{
TimedSection s("cout with string constant and '\\n'");
for (int i = 0; i < iters; ++i)
std::cout << "01234567890123456789\n";
}
{
TimedSection s("printf with string constant and '\\n'");
for (int i = 0; i < iters; ++i)
printf("01234567890123456789\n");
}
{
TimedSection s("cout with some stuff and endl");
for (int i = 0; i < iters; ++i)
std::cout << text << "01234567890123456789" << i << std::endl;
}
{
TimedSection s("cout with some stuff and '\\n'");
for (int i = 0; i < iters; ++i)
std::cout << text << "01234567890123456789" << i << '\n';
}
{
TimedSection s("printf with some stuff and '\\n'");
for (int i = 0; i < iters; ++i)
printf("%s01234567890123456789%i\n", text, i);
}
}
我想指出的是,如果你想在c++中使用线程,如果你使用cout,你可以得到一些有趣的结果。
考虑下面的代码:
#include <string>
#include <iostream>
#include <thread>
using namespace std;
void task(int taskNum, string msg) {
for (int i = 0; i < 5; ++i) {
cout << "#" << taskNum << ": " << msg << endl;
}
}
int main() {
thread t1(task, 1, "AAA");
thread t2(task, 2, "BBB");
t1.join();
t2.join();
return 0;
}
// g++ ./thread.cpp -o thread.out -ansi -pedantic -pthread -std=c++0x
现在,输出都被打乱了。它也可以产生不同的结果,试着执行几次:
##12:: ABABAB
##12:: ABABAB
##12:: ABABAB
##12:: ABABAB
##12:: ABABAB
你可以使用printf,也可以使用互斥。
#1: AAA
#2: BBB
#1: AAA
#2: BBB
#1: AAA
#2: BBB
#1: AAA
#2: BBB
#1: AAA
#2: BBB
玩得开心!
对我来说,真正的区别是让我选择'cout'而不是'printf':
1) <<操作符可以为我的类重载。
2) cout的输出流可以很容易地更改为一个文件: (:复制粘贴:)
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
streambuf* sbuf = cout.rdbuf();
cout.rdbuf(file.rdbuf());
cout << "This is sent to file" << endl;
cout.rdbuf(sbuf);
cout << "This is also sent to prompt" << endl;
return 0;
}
3)我发现cout更具可读性,特别是当我们有很多参数时。
cout的一个问题是格式化选项。在printf中格式化数据(精度,合理性等)更容易。
推荐文章
- cplusplus.com给出的错误、误解或坏建议是什么?
- 找出质数最快的算法是什么?
- c++枚举类可以有方法吗?
- 格式化IO函数(*printf / *scanf)中的转换说明符%i和%d之间的区别是什么?
- 将析构函数设为私有有什么用?
- main()中的Return语句vs exit()
- 为什么c#不提供c++风格的'friend'关键字?
- 在函数的签名中添加关键字
- 我如何在Visual Studio中预处理后看到C/ c++源文件?
- 为什么在标准容器中使用std::auto_ptr<>是错误的?
- 用比较double和0
- 保护可执行文件不受逆向工程的影响?
- 在c++中字符串前面的“L”是什么意思?
- 为什么std::map被实现为红黑树?
- 空括号的默认构造函数