【问题标题】:Comparison between the two printf statements两个 printf 语句之间的比较
【发布时间】:2011-07-20 15:24:06
【问题描述】:

请看下面两个c语句

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

他们产生相同的结果,但肯定有一些区别在引擎盖下,那么有什么区别,哪个更好 ?请分享您的想法!

【问题讨论】:

  • '幕后',你的意思是?我不认为有太多人会担心 printf 在内部做什么。
  • 这个问题是非常具体的实现
  • 最好使用puts("a very long string")
  • @Sander: 但是puts 在字符串的末尾添加了一个换行符......也许fputs

标签: c string compiler-construction printf


【解决方案1】:

如果你知道字符串的内容是什么,你应该使用第一种形式,因为它更紧凑。如果您要打印的字符串可能来自用户或任何其他来源,而您不知道字符串内容是什么,则必须使用第二种形式;否则,您的代码将对format string injection attacks 开放。

【讨论】:

  • format-string-injection-attacks 对我来说是新的,无论如何非常感谢。
【解决方案2】:

第一个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

【讨论】:

  • 这个解释还强调了格式注入的安全风险,正如@Aasmund Eldhuset 在单独的答案中所解释的那样。 IE。如果您不知道“非常长的字符串”中的确切内容,那么您应该从不执行第一个选项,而应使用第二个 %s 选项或 puts 调用。
  • 我同意这回答了这个问题,但我想强调的是,如果您非常担心性能,那么您可能不应该使用 puts 等而不是 printf
【解决方案3】:

第一个传一个参数,第二个传2个,所以第一个调用会稍微快一点。

但在第一个中,printf() 必须扫描长字符串以获取格式规范,而在第二个中,格式字符串非常短,因此在第二个中实际处理可能更快。

更重要的是(无论如何对我来说),“一个非常长的字符串”不太可能是一个常量字符串,就像在这个例子中一样。如果你正在打印一个长字符串,你可能使用了一个指向程序生成的东西的指针。在这种情况下,使用第二种形式是一个更好的主意,因为在其他地方,不知何故,有时,长字符串将包含格式 printf 格式规范,这将导致 printf 去寻找另一个参数,你的程序会崩溃。大约一周前,在我们使用了近 20 年的代码中,这个确切的问题刚刚发生在我身上。

底线是您的 printf 格式规范应该始终是一个常量字符串。如果需要输出变量,请使用printf("%s",var) 或更好的fputs(var, stdout)

【讨论】:

    【解决方案4】:

    第一个效率不亚于第二个。由于没有格式序列和相应的参数,因此 printf() 函数不必做任何工作。在第二种情况下,如果编译器不够聪明,无法捕捉到这一点,您将调用不必要的工作(注意:与在终端实际发送(和读取!)输出相比微不足道。

    【讨论】:

      【解决方案5】:

      printf 专为使用格式化打印而设计。尽管不是必需的,但为调试目的提供格式化参数会更有用。

      %s 接受一个 const char* 的值,而没有留下任何参数只是打印文字表达式。

      您仍然可以显式地将不同的指针转换为 const char* 并更改其内容而不更改输出表达式。

      【讨论】:

        【解决方案6】:

        首先你应该更好地定义“更好”,因为它本身还不够聪明。以什么方式更好?性能、维护、可读性、可扩展性...

        通过提供的一行代码,我会为几乎所有版本的“更好”选择选项 1

        • 更易读
        • 它只做它应该做的,仅此而已(KISS 原则)
        • 它更快(没有毫无意义的移动内存来将一个字符串塞入另一个字符串)。但除非您在循环中多次执行此 printf,否则这并不是一个很大的优势。

        【讨论】:

        • 你的建议很好,我没有定义“更好”的原因是我不想限制它可以进入的方式,所以人们可以分享他出来的任何东西。
        猜你喜欢
        • 2018-12-31
        • 2013-01-04
        • 2019-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-29
        • 2013-09-25
        相关资源
        最近更新 更多