printf() 在没有双引号的情况下工作,打印随机字符
printf() working without double quotes, prints random characters
我在一次大学测试中偶然发现了这段 C 代码,当我在 Dev-C++ 5.11 编译器上测试它时,它打印了随机字符。我不明白这段代码是如何或为什么起作用的。有人可以启发我吗?
int main() {
char a[10] = "%s" ;
printf( a ) ;
}
printf
函数签名为:
int printf(const char *format, ...);
它期望格式字符串作为第一个参数和可变数量的参数,这些参数根据格式字符串中的格式说明符进行处理和打印。您问题中的变量 a
正在为其提供格式字符串。随机字符的原因是缺少格式说明符 %s
的参数。以下将正确打印字符串:
printf( a, "Hello World!" );
可以在此处查看格式说明符列表 https://en.wikipedia.org/wiki/Printf_format_string
为什么编译通过?
因为 printf
接受的可变参数在 运行 时处理。并非所有编译器都会在编译时检查格式字符串是否验证参数。即使他们这样做了,他们最多也会发出警告,但仍然会编译程序。
它使用字符串 "%s" 作为格式字符串,并使用未初始化的内存作为 "data"。
它这样做的唯一原因 "something" 是因为编译器显然不够聪明,无法识别格式字符串需要一个参数而提供了零个参数。或者因为编译器警告被忽略 and/or 错误被关闭。
仅供遇到此问题的任何人参考:"Always leave all warnings and errors enabled and fix your code until they're gone"这不能保证正确的行为,但确实会降低 "mysterious" 出现问题的可能性。
这道题有两个部分:遗漏的引号和随机字符。
printf()
只是一个函数。您可以将字符串和其他值作为参数传递给函数。您不必使用文字。您可以同时使用 char *a = "something"; printf(a)
(将变量作为参数传递)和 printf("something")
(将字符串文字作为参数传递)。
printf()
也是一个variadic function。这意味着它可以接受任意数量的参数。您可以使用 printf("hello world")
、printf("%s", "hello world")
甚至 printf("%s %s", "hello", "world")
。一些较旧的编译器不会根据第一个参数(格式字符串)验证您是否确实传递了正确数量的参数。这就是为什么您的代码即使缺少参数也能编译的原因。当程序运行时,代码遍历格式字符串,看到 "%s"
并查找第二个参数以将其打印为字符串。由于没有第二个参数,它基本上读取随机内存并且你得到垃圾字符。
我在一次大学测试中偶然发现了这段 C 代码,当我在 Dev-C++ 5.11 编译器上测试它时,它打印了随机字符。我不明白这段代码是如何或为什么起作用的。有人可以启发我吗?
int main() {
char a[10] = "%s" ;
printf( a ) ;
}
printf
函数签名为:
int printf(const char *format, ...);
它期望格式字符串作为第一个参数和可变数量的参数,这些参数根据格式字符串中的格式说明符进行处理和打印。您问题中的变量 a
正在为其提供格式字符串。随机字符的原因是缺少格式说明符 %s
的参数。以下将正确打印字符串:
printf( a, "Hello World!" );
可以在此处查看格式说明符列表 https://en.wikipedia.org/wiki/Printf_format_string
为什么编译通过?
因为 printf
接受的可变参数在 运行 时处理。并非所有编译器都会在编译时检查格式字符串是否验证参数。即使他们这样做了,他们最多也会发出警告,但仍然会编译程序。
它使用字符串 "%s" 作为格式字符串,并使用未初始化的内存作为 "data"。
它这样做的唯一原因 "something" 是因为编译器显然不够聪明,无法识别格式字符串需要一个参数而提供了零个参数。或者因为编译器警告被忽略 and/or 错误被关闭。
仅供遇到此问题的任何人参考:"Always leave all warnings and errors enabled and fix your code until they're gone"这不能保证正确的行为,但确实会降低 "mysterious" 出现问题的可能性。
这道题有两个部分:遗漏的引号和随机字符。
printf()
只是一个函数。您可以将字符串和其他值作为参数传递给函数。您不必使用文字。您可以同时使用char *a = "something"; printf(a)
(将变量作为参数传递)和printf("something")
(将字符串文字作为参数传递)。printf()
也是一个variadic function。这意味着它可以接受任意数量的参数。您可以使用printf("hello world")
、printf("%s", "hello world")
甚至printf("%s %s", "hello", "world")
。一些较旧的编译器不会根据第一个参数(格式字符串)验证您是否确实传递了正确数量的参数。这就是为什么您的代码即使缺少参数也能编译的原因。当程序运行时,代码遍历格式字符串,看到"%s"
并查找第二个参数以将其打印为字符串。由于没有第二个参数,它基本上读取随机内存并且你得到垃圾字符。