You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中printf的%p处理数组与指针的行为差异疑问

数组名与地址输出的疑惑解答

问题描述

在第一个printf中,输出的是arr的地址,这符合预期。但第二个printf也输出了相同的地址,它难道不应该输出arr指向的“值”(即地址0)吗?

代码示例

char * arr[2];
char ** p;

int main(){
 p = arr;

 printf("%p\n",&arr);
 printf("%p\n",arr);

 printf("%p\n",&p);
 printf("%p\n",p);

 /* OUTPUT 
 0x10aa71010
 0x10aa71010
 0x10aa71020
 0x10aa71010
 */
}

核心原因解析

  • 数组名的隐式转换规则:C语言中,数组名arr在多数表达式场景下会自动转换为指向数组第一个元素的指针(即&arr[0])。此时arr的类型从char*[2](数组类型)转为char**(指针类型),但它的地址值和数组的起始地址完全一致——因为数组的起始位置就是第一个元素的起始位置。
  • &arr的本质:&arr是取整个数组的地址,类型为char*(*)[2](指向数组的指针),它的地址值同样是数组的起始地址,所以和arr转换后的指针值打印出来完全相同。两者的区别仅在于类型和指针步长:对&arr做自增操作会跳过整个数组的大小,而对arr转换后的指针自增只会跳过一个元素的大小。
  • 关于“输出arr指向的值”的误解:arr本身是数组,不是指针,它不“指向”任何值——数组是一块连续内存,用来存放元素。你误以为它会输出0,是混淆了数组名和指针的概念。数组中的元素arr[0]、arr[1]才是char*类型的指针,由于arr是全局数组,元素会被默认初始化为0,若要输出这个值,需要访问数组元素而非数组名本身。

验证方法

如果要输出数组第一个元素存储的地址(也就是你以为的“arr指向的值”),修改代码中的printf语句:

printf("%p\n", *arr); // 等价于 printf("%p\n", arr[0]);

此时会输出0x0,这才是你想要的结果。


内容的提问来源于stack exchange,提问作者user18503064

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:27:29