C语言中printf用%s和%p时数组名为何表示不同值?
数组名在printf不同格式符下的表现解析
核心原因在于两点:数组名的隐式转换规则,以及printf不同格式符的处理逻辑。
1. 数组名的隐式转换
对于代码里的char name1[10] = "name1";,当你把name1作为参数传给printf时,它会自动转换成&name1[0]——也就是指向数组第一个字符'n'的指针。这时候你传入printf的本质是一个地址值,和char* name2(malloc返回的指针)是同一种类型(char*)。
2. 不同格式符的处理逻辑
- %p格式符:作用就是直接输出指针的地址值,所以不管是数组名转成的指针,还是malloc返回的指针,都会打印对应的内存地址,这和你的预期一致。
- %s格式符:要求传入指向字符串首字符的指针,然后从这个地址开始,逐个读取并打印字符,直到遇到字符串结束符
'\0'为止。这就是直接传name1能输出整个字符串的原因——%s本身就是靠地址遍历字符串的,不需要手动解引用。要是传*name1,你传入的是首字符'n'的ASCII值,printf会把这个值当成地址去访问,大概率会导致程序崩溃或输出乱码。
3. 格式符改成%d的情况
如果换成%d,printf会把你传入的指针地址当成十进制整数解析,输出的是地址的十进制数值。这不是数组名变了,而是printf对同一个地址值的解析方式变了。
代码验证
// 为何仅将格式符从%s改为%d时,数组名会表示不同值? //====== array ======= char name1[10] = "name1"; printf("%s \n", name1); // prints name1 printf("%p \n", name1); // prints address //====== malloc ======= char* name2 = (char*)malloc(10); strcpy(name2, "name2"); printf("%s \n", name2); // prints name2 printf("%p", name2); // prints address
内容的提问来源于stack exchange,提问作者user20766406
相关产品推荐
相关产品推荐

