C语言二维数组解引用相关技术疑问咨询
关于C语言二维数组的那些疑问,一次讲清楚
咱们一步步拆解你的问题,先从二维数组的本质说起:
1. arr的值到底是什么?
在C语言里,int arr[2][3]是一个数组的数组——它包含2个元素,每个元素本身又是一个能装3个int的数组。当你直接使用数组名arr时(除了用sizeof(arr)或者&arr的情况),它会被自动转换成指向第一个元素的指针。这里的第一个元素是arr[0](也就是那个长度为3的int数组),所以arr的类型是int (*)[3](可以理解为“指向包含3个int的数组的指针”)。
2. arr是arr[0][0]的地址吗?
从数值上看,arr和&arr[0][0]是相等的——因为数组的起始内存地址就是它第一个元素的第一个元素的地址。但它们的类型完全不同:
arr转成的指针类型是int (*)[3](指向数组的指针)&arr[0][0]的类型是int *(指向单个int的指针)
这种类型差异就是你后面遇到问题的核心原因。
3. 为什么printf("%d", *arr);不输出10?
咱们拆解*arr的行为:
*arr是对arr这个指向数组的指针做解引用,得到的是arr[0]——也就是那个长度为3的int数组。- 而当
arr[0]作为表达式使用时,它又会被转换成指向自己第一个元素的指针,也就是&arr[0][0],类型是int *。
所以你用%d格式符去打印这个指针的数值,得到的其实是arr[0][0]所在的内存地址(就是你看到的那个“奇怪的数字”),而不是它的值10。
怎么改才能输出10?
如果要打印arr[0][0]的值,你需要再做一次解引用:
printf("%d", **arr);
或者写成更直观的形式:
printf("%d", arr[0][0]); // 或者等价于 printf("%d", *(*arr));
另外补充个小知识点:你在函数foo里写的void foo(int arr[2][3]),编译器其实会把它当成void foo(int (*arr)[3])——函数参数里的数组声明都会被转换成指向数组元素的指针,不管你写的是几维数组。
内容的提问来源于stack exchange,提问作者Mike T
相关产品推荐
相关产品推荐

