在使用C/C++編寫控制檯應用或acm競賽的時候,I/O方式無非是標準輸入輸出,特別是acm競賽,就本人來講,由C語言入門,輸入方式還只會scanf
,自從學了C++,便深深地被 cin/cout
輸入輸出流的簡潔用法所吸引,相信有這種感受的不止我一我的。
因此很長一段時間,平常的訓練和各類線上比賽,再也沒有使用過scanf
,反手一個cin
感受很炫酷。然而好景不長,一次bestcoder的常規線上賽,前期發揮穩定,手感至關好,1001和1002快而準地ac,1003也很快來了思路(兩年前的事情了,細節什麼的早忘了),咔咔咔敲完代碼提交ac,最後剩下充足的時間攻克1004,雖然到結束也沒作出來,可是3題鐵定漲分啊……
然而終判的結果讓我大吃一鯨,T!L!E!,竟然超時,百思不得其解之時(其實以前知道cin
效率低,可是用着太順手了就沒在乎),想到了會不會是數據太多?而後等着終判結束題目開放,抱着試一試的心態,把cin
改爲了scanf
,而後……竟然……秒過……
而後網上查閱資料(只說輸入,輸出大同小異),cin慢的緣由不少,其中很重要的一點是爲了使cin
與scanf
能夠兼容混合使用,cin
在內部實現的時候會同步輸入緩衝區,也就是說,輸入流會時刻與輸入緩衝保持同步,這是一個很耗時的操做,因此就致使了在大量輸入數據的時候,cin
會比scanf
慢不少,能夠說,這個慢,是數量級上的差別。
若是你能夠保證程序中不會出現標準輸入與流輸入混用的狀況,能夠在程序開始時使用ios::sync_with_stdio(false);
關閉同步來提升速度,可是在大量數據面前輸入速度仍顯得乏力,相比scanf
仍是慢了一些(上面說的1003題我用cin
關同步仍是超時,只有scanf
能過),我的認爲緣由在於對輸入流對象的封裝和>>
這個符號的運算符重載致使執行時間變慢。
因此從那之後,在acm生涯裏再也沒有使用過cin
……硬生生地改回了scanf
的習慣。簡潔和效率總要捨棄一個,對於算法競賽來講,效率纔是關鍵吧……ios
說了這麼多cin與scanf的速度比較,接下來重點說一下scanf,用法沒必要多說,結合多年來競賽經驗,介紹一下格式符%c與其餘格式符的區別和特定使用場景的注意事項。算法
%c
是一個很奇葩的設定,單獨讀入一個字符,包括不可見的控制字符(換行等),而其餘格式化符號(如%d %lld %f %lf %s
等)會在讀入未完成時將換行符、空格、製表符等空白字符通通捨棄忽略,直到讀到了足夠的數據或遇到文件結尾才結束。咱們平時控制檯輸入時一般按行輸入,也就是輸入數據後要敲擊回車才能被讀取,這樣就致使了換行符在%c
與其餘格式符號並存的程序中出現各類問題,例如沒法得到理想輸入數據,字符串錯誤錯誤致使程序崩潰等。優化
總結下來就是:指針
①scanf至少要比cin快一倍左右code
②cin慢的緣由:默認狀況,cin與stdin老是保持同步的,也就是說這兩種方法能夠混用,而沒必要擔憂文件指針混亂,同時cout和stdout也同樣,二者混用不會輸出順序錯亂。正由於這個兼容性的特性,致使cin有許多額外的開銷。(解決:只需一個語句std::ios::sync_with_stdio(false);,這樣就能夠取消cin於stdin的同步了,此時的cin就與scanf差很少了)對象
③cin、cout是在編譯期間就決定了讀入變量的類型。而scanf()是在運行期決定的,編譯器沒法優化,並且還要識別字符串。理論上scanf比cin要慢不少,實際上快的緣由是不少編譯器對cin、cout的處理過於保守。ci
④同牛人建議,Acmer 儘可能用scanf,printf來進行輸入輸出吧....字符串