printf()在没有双引号的情况下工作,打印随机字符

时间:2018-06-05 16:18:36

标签: c printf dev-c++

我在大学测试中偶然发现了这个C代码,当我在Dev-C ++ 5.11编译器上测试它时,它打印出随机字符。我无法理解这段代码的工作原理或原因。有人可以开导我吗?

 int main() {
        char a[10] = "%s" ;
        printf( a ) ;
    }

3 个答案:

答案 0 :(得分:1)

printf函数签名是:

int printf(const char *format, ...);

它希望格式字符串作为第一个参数和可变数量的参数,这些参数是根据格式字符串中的格式说明符处理和打印的。你问题中的变量a正在为它提供格式字符串。随机字符的原因是缺少格式说明符%s的参数。以下将正确打印字符串:

printf( a, "Hello World!" );

这里可以看到格式说明符列表https://en.wikipedia.org/wiki/Printf_format_string

为什么要编译?

因为printf接受的可变参数在运行时被处理。并非所有编译器都会编译时间检查以验证格式字符串的参数。即使他们这样做,他们最多也会发出警告,但仍然会编译程序。

答案 1 :(得分:1)

它使用字符串“%s”作为格式字符串,并使用未初始化的内存作为“数据”。

它做“某事”的唯一原因是因为编译器显然不够聪明,无法识别格式字符串需要一个参数并且提供了零参数。或者因为忽略了编译器警告和/或关闭了错误。

对于任何碰到这个问题的人来说只是一个FYI:“始终保持启用所有警告和错误并修复代码,直到它们消失为止”这不保证正确的行为,但确实使“神秘”问题不太可能发生。

答案 2 :(得分:1)

这个问题有两个部分:缺少引号和随机字符。

  1. printf()只是一个功能。您可以将字符串和其他值作为参数传递给函数。你不必使用文字。您可以同时使用char *a = "something"; printf(a)(将变量作为参数传递)和printf("something")(将字符串文字作为参数传递)。
  2. printf()也是enter image description here。这意味着它可以接受任意数量的参数。您可以使用printf("hello world")printf("%s", "hello world")甚至printf("%s %s", "hello", "world")。一些较旧的编译器不会根据第一个参数(即格式字符串)验证您是否实际传递了正确数量的参数。这就是为什么你的代码编译即使它缺少一个参数。当程序运行时,代码遍历格式字符串,看到"%s"并查找第二个参数以将其作为字符串打印。由于没有第二个参数,它基本上读取随机内存,你会得到垃圾字符。