2011-07-20 144 views
2

請看看以下兩個C語句兩個printf語句比較

printf("a very long string"); 
printf("%s","a very long string"); 

他們生產的相同的結果,但肯定是有罩下的一些差異,所以什麼區別和哪一個是更好?請分享你的想法!

+8

'引擎蓋下',你的意思是?我不認爲太多的人會擔心printf在內部做什麼。 –

+0

這個問題很具體的實現是 – Necrolis

+2

更好的可能是使用'puts(「一個很長的字符串」)'。 –

回答

13

如果你知道字符串內容是什麼,你應該使用第一種形式,因爲它更緊湊。如果要打印的字符串可以來自用戶或來自任何其他來源,以至於您不知道字符串內容是什麼,那麼必須使用使用第二種形式;否則,您的代碼將會廣泛開放至format string injection attacks

+0

format-string-injection-attacks對我來說是新的,無論如何非常感謝。 – Tracy

0

第一個效率不低於第二個。由於沒有格式序列並且沒有相應的參數,因此printf()函數不能執行任何工作。在第二種情況下,如果編譯器沒有足夠的智能來解決這個問題,那麼您將需要進行不必要的工作(注意:與實際發送(和讀取!)相比,終端輸出實際上是微乎其微。)

5

第一個printf是這樣工作的

'a' is not a special character: print it 
' ' is not a special character: print it 
'v' is not a special character: print it 
... 
'g' is not a special character: print it 

第二printf作品這樣

'%' is a special character: 
    's' print the contents of the string pointed to by the 2nd parameter 
+0

此解釋還突出了格式注入的安全風險,如@Aasmund Eldhuset在單獨的答案中所解釋的那樣。 I.e.如果你不知道「非常長的字符串」中的確切內容是什麼,那麼你應該首先選擇第一個選項,而不是使用第二個%s選項或put命令。 – Soren

+0

我同意這回答了這個問題,但我想強調的是,如果您擔心表現如此之大,那麼您應該不會使用puts等,而不是printf – user606723

1

第一個通過一個參數和所述第二傳遞2,因此呼叫稍快於第一個是。

但是在第一個例子中,printf()必須掃描長字符串以獲得格式規範,而第二個格式字符串非常短,所以實際處理速度可能會更快。

更重要的是(對我來說),「很長的字符串」不可能是一個常量字符串,因爲它在這個例子中。如果你正在打印一個長字符串,你可能使用了一個指向程序生成的東西的指針。在這種情況下,使用第二種形式是更好的主意,否則在某種程度上,某種程度上,長字符串將包含格式printf格式規範,這將導致printf去查找另一個參數,並且程序將崩潰。這個確切的問題剛剛發生在我大約一週前的代碼中,我們已經使用了近20年。

底線是你的printf格式規範應該總是一個常量字符串。如果需要輸出變量,請使用printf("%s",var)或更好,fputs(var, stdout)

+0

感謝您的解釋。 – Tracy

0

printf設計用於打印格式。爲了調試而提供格式化參數更加有用,儘管它們不是必需的。

%s取得一個const char *的值,而不留下參數只是輸出文字表達式。

您仍然可以明確指定const char *的不同指針,並在不更改輸出表達式的情況下更改其內容。

0

首先,你應該更好地定義「更好」,因爲它本身不夠聰明。以什麼方式更好?性能,維護,可讀性,可擴展性...

隨着一行代碼提交我會選擇選項1的「好」

  • 幾乎所有版本,它更readible
  • 它做什麼,它應該做的,僅此而已(KISS原則)
  • 速度更快(將一個字符串填充到另一個字符串中並沒有無意義的移動內存)。但是除非你在循環中多次做這個printf,這並不是什麼大好事。
+0

你的建議很好,我之所以沒有定義「更好」,是因爲我不想限制它可以進入的方式,所以人們可以分享他出來的任何東西。 – Tracy