printf第一个参数仅允许字符串字面量吗?为何3+"helloWorld"调用无报错?
关于printf第一个参数是否仅允许字符串字面量的疑问解答
首先明确说:printf的第一个参数绝对不是只能传字符串字面量,它的要求只是一个指向以\0结尾的字符序列的const char*指针——只要符合这个条件,不管指针来源是什么,语法和语义上都是合法的(当然前提是指针指向的内存是有效的)。
咱们来拆解你提到的printf(3+"helloWorld");例子:
- 在C语言里,字符串字面量
"helloWorld"本质上是一个char数组,在表达式中会自动转换成指向数组第一个元素(也就是'h')的char*指针。 3+"helloWorld"是C里的指针算术操作:当你给一个指向char的指针加上整数n,指针会向后偏移n个char的长度。这里偏移3位后,指针就指向了原字符串中第4个字符'l',所以这个表达式的结果就是指向"loWorld"的char*指针。- 这个指针完全符合
printf第一个参数const char* format的类型要求,所以编译器不会报错,运行时printf就从这个指针指向的位置开始输出,直到遇到\0,也就是你看到的loWorld。
再看你贴出的printf定义代码:
#include <libioP.h> #include <stdarg.h> #include <stdio.h> #undef printf /* Write formatted output to stdout from the format string FORMAT. */ /* VARARGS1 */ int __printf(const char *format, ...) { va_list arg; int done; va_start(arg, format); done = vfprintf(stdout, format, arg); va_end (arg); return done; } #undef _IO_printf ldbl_strong_alias(__printf, printf); /* This is for libg++. */ ldbl_strong_alias(__printf, _IO_printf);
这里__printf的第一个参数明确是const char *format——只要是合法的const char*都能传,字符串字面量只是其中一种常见的输入形式而已。
不过要提醒一句:如果传入的指针没有指向一个以\0结尾的有效字符串,那会触发未定义行为(比如读取超出内存范围的内容),但你的例子里是安全的,因为"helloWorld"本身长度足够,偏移后仍然在字符串的有效范围内,且末尾有\0。
内容的提问来源于stack exchange,提问作者Sushil Patel
相关产品推荐
相关产品推荐

