数组指针行为解析:为何&arr[0]与arr[0]表现一致?
为什么&arr[0]和arr[0]在代码中表现相同?
第一版代码
#include<stdio.h> void Multiplication(int arr[][10], int num,int size); int main(){ int arr[3][10]; Multiplication(&arr[0],2,3); Multiplication(&arr[1],7,3); Multiplication(&arr[2],9,3); for(int i=0;i<3;i++){ printf("\nMultiplication Table of %d\n",arr[i][0]); for(int j=0;j<10;j++){ printf("%d * %d = %d\n",arr[i][0],j,arr[i][j]); } } return 0; } void Multiplication(int arr[][10], int num, int size){ for(int j=0;j<size;j++){ for(int i=0;i<10;i++){ arr[j][i] = num * (i+1); } } }
第二版精简代码
#include<stdio.h> void Multiplication(int *arr, int num,int size); int main(){ int arr[3][10]; Multiplication(arr[0],2,3); Multiplication(arr[1],7,3); Multiplication(arr[2],9,3); for(int i=0;i<3;i++){ printf("\nMultiplication Table of %d\n",arr[i][0]); for(int j=0;j<10;j++){ printf("%d * %d = %d\n",arr[i][0],j,arr[i][j]); } } return 0; } void Multiplication(int *arr, int num,int size){ for(int i=0;i<10;i++){ arr[i] = num * (i+1); } }
问题解析
你观察到的&arr[0]和arr[0]表现相同,本质是C语言数组的地址特性导致的:
arr[0]是二维数组arr的第一个一维子数组(长度为10的int数组)。在表达式中,一维数组名会自动转换为指向其第一个元素的指针,也就是int*类型,指向的是arr[0][0]的内存地址。&arr[0]是取这个一维子数组的地址,它的类型是int (*)[10](指向长度为10的int数组的指针),但这个地址的数值和arr[0]转换后的指针数值完全一致——因为数组的起始地址和它第一个元素的起始地址在内存中是同一个位置。
再结合你代码里的函数调用来看:
- 第一版的
Multiplication函数参数int arr[][10],编译器会把它解析为int (*arr)[10],和&arr[0]的类型匹配,传递过去后能正确访问数组元素。 - 第二版的函数参数是
int*,arr[0]转换后的int*指针正好匹配这个参数类型,同样能正确访问连续的内存单元。
虽然两者的类型不同,但因为地址数值相同,且你的函数操作都是针对连续内存的元素赋值,所以最终表现出了相同的效果。
内容的提问来源于stack exchange,提问作者RACHIT MITTAL
相关产品推荐
相关产品推荐

