相信使用C++的人都有一種迷惑或者是不自信:在輸入輸出的時候是不是應該使用scanf/printf
更好呢,因為傳說cin/cout
龜速,我當時也長期被這個所困擾,后來在閱讀C++ primer第五版的時候我自己做了一個測試,發現如果不使用std::ios_sync_with_stdio(false);
關閉和C庫函數的同步的話的確scanf/printf
快很多,大概相差五倍,但是如果關閉同步的話,cin/cout
是比scanf/printf
快8%-10%的。(這兩個數據是我后面看別人測量的,我自己只是簡單測量了一下)
之所以關閉緩沖以后cin/cout
比較快,是因為cin/cout
對輸入參數和類型的推斷是在編譯時確定的,而scanf/printf
是在運行時確定的。
在我以前的一篇博客:C++Primer學習筆記:第1章 開始中我提到了這一點。
如果認為我自己的測量可能有誤差,可以看一下大神們的回答:
Cin-Cout vs Scanf-Printf
Using scanf() in C++ programs is faster than using cin?
和我的說法是一致的,以后被人懟你怎么還用cin/cout
的時候,你可以拿出這些測評讓他們瞧瞧,我們也應該對C++自信起來,不要想著C++沒有C底層好像速度就差一些。
但是之前參加競賽的時候,我信心滿滿地使用cin/cout
進行輸入輸出,卻總是TEL,我以為是程序算法的問題,檢查了好久好久,最后才發現是因為使用了cin/cout
的原因,改成scanf/printf
后程序就AC了,看到這里你是不是心里一驚:搞什么嘛,上面的測評都是唬人的嘛
其實之所以即使關閉了和C庫的同步,我的程序還會TEL和cin/cout
沒有什么關系,罪魁禍首是endl
,相信很多學習C++的人都和我一樣,習慣了使用endl
進行換行,同時刷新緩沖區,一舉兩得,美滋滋,但是其實正是因為endl
會強制刷新緩沖區,導致頻繁的IO操作,使得程序效率迅速降低。因此除非是使用打樁調試(就是及時輸出調試信息,因為這里我們要求輸出信息有時效性,所以要及時刷新緩沖區),否則都不要使用endl
,而使用\n
進行換行。
知道了這兩點:
std::ios::sync_with_stdio(false);
cout << "Hello world" << "\n";
我們就可以放心地使用cin/cout
進行輸入輸出啦,而且效率肯定是最快的。
在使用cin
進行循環讀入的時候可能會遇到一點問題,可以參考一下我以前寫的一篇博客:C++ cin 實現循環讀入
有了上面的準備,我們就可以使用cin/cout
開心地寫代碼啦。