为什么C语言二维数组名的值与单次解引用后的值均为数组首地址?
C语言二维数组解引用问题解答
核心原理:数组的类型降级规则
你定义的int s[4][2]是元素类型为int[2]的数组,并非指针数组,遵循C语言的数组自动降级规则:
- 数组名在绝大多数表达式场景下,会自动转换为指向其首元素的指针,类型由数组元素决定
- 此处
s的原始类型是int [4][2],降级后为指向首元素的指针,类型是int (*)[2](指向长度为2的int数组的指针),所以直接打印s得到的是整个二维数组的首地址
单层解引用*s为什么还是地址?
*s等价于s[0],它的类型是int [2](长度为2的一维int数组),这个值作为数组在printf参数中又会触发一次降级规则,自动转换为指向该一维数组首元素的int*类型指针,对应的值就是第一个一维数组的首地址。
整个二维数组的首地址、第一个一维数组的首地址、第一个一维数组第一个元素的地址,三者的数值完全重合,只是对应的类型不同,所以你打印
s和*s会得到相同的数值结果
为什么**s才能拿到1234?
**s等价于*(*s),也就是对已经降级为int*的首元素指针再做一次解引用,最终得到的才是int类型的数值,也就是s[0][0]的取值1234。
额外注意事项
- 打印内存地址应该使用
%p格式符,且需要将参数强制转换为void*类型,你用%u打印地址属于未定义行为,在64位等地址长度超过unsigned int长度的平台上会出现输出错误 - 可以通过sizeof操作验证不同取值的类型差异:
sizeof(s)的结果是32(4个一维数组 × 每个数组2个int × int占4字节),sizeof(*s)的结果是8(2个int × 4字节),sizeof(**s)的结果是4(单个int的长度)
内容的提问来源于stack exchange,提问作者0xhackdevel
相关产品推荐
相关产品推荐

