printf()和cout在c++中的区别是什么?
当前回答
Printf是一个函数而cout是一个变量。
其他回答
我想指出的是,如果你想在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
玩得开心!
我想说,printf的可扩展性不足是不完全正确的: 在C语言中,它是真的。但是在C语言中,没有真正的类。 在c++中,可以重载强制转换操作符,因此,重载char*操作符并像这样使用printf:
Foo bar;
...;
printf("%s",bar);
可以是可能的,如果Foo重载好的操作符。或者你有一个好方法。简而言之,printf对我来说和cout一样具有可扩展性。
我可以看到c++流的技术参数(一般来说…不仅是cout.)是:
类型安全。(顺便说一下,如果我想打印一个'\n',我使用putchar('\n')…我不会用核弹杀死一只昆虫。) 更容易学。(不需要学习“复杂的”参数,只需使用<<和>>操作符) 本机使用std::string(对于printf有std::string::c_str(),但对于scanf?)
对于printf,我看到:
更容易,或至少更短(就书写的字符而言)复杂的格式。对我来说,可读性更强(我猜是品味问题)。 更好地控制函数所生成的内容(返回写入了多少字符并且有%n格式化程序:"Nothing printing . "参数必须是一个指向有符号整型的指针,其中存储到目前为止写入的字符数。”(from printf - c++ Reference) 更好的调试可能性。原因和上一个论点一样。
我个人倾向于使用printf(和scanf)函数,主要是因为我喜欢短行,而且我认为打印文本时的打字问题并不难避免。 我唯一对c风格函数感到遗憾的是std::string不受支持。在将其交给printf之前,我们必须通过一个char*(如果我们想读,则使用std::string::c_str(),但如何写?)
来自c++常见问题解答:
[15.1] Why should I use <iostream> instead of the traditional <cstdio>? Increase type safety, reduce errors, allow extensibility, and provide inheritability. printf() is arguably not broken, and scanf() is perhaps livable despite being error prone, however both are limited with respect to what C++ I/O can do. C++ I/O (using << and >>) is, relative to C (using printf() and scanf()): More type-safe: With <iostream>, the type of object being I/O'd is known statically by the compiler. In contrast, <cstdio> uses "%" fields to figure out the types dynamically. Less error prone: With <iostream>, there are no redundant "%" tokens that have to be consistent with the actual objects being I/O'd. Removing redundancy removes a class of errors. Extensible: The C++ <iostream> mechanism allows new user-defined types to be I/O'd without breaking existing code. Imagine the chaos if everyone was simultaneously adding new incompatible "%" fields to printf() and scanf()?! Inheritable: The C++ <iostream> mechanism is built from real classes such as std::ostream and std::istream. Unlike <cstdio>'s FILE*, these are real classes and hence inheritable. This means you can have other user-defined things that look and act like streams, yet that do whatever strange and wonderful things you want. You automatically get to use the zillions of lines of I/O code written by users you don't even know, and they don't need to know about your "extended stream" class.
另一方面,printf要快得多,因此在非常特定和有限的情况下,可以优先使用它而不是cout。总是先做侧写。(例如,参见http://programming-designs.com/2009/02/c-speed-test-part-2-printf-vs-cout/)
cout<< "Hello";
printf("%s", "Hello");
两者都用于打印值。它们有完全不同的语法。c++两者都有,C 只有printf。
人们经常声称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);
}
}