2011-07-20 103 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