二维数组指针传递后无法用下标访问的疑问及语法验证
二维数组与指针的核心疑问解答
为什么int*指针无法用v[1][1]访问二维数组?
首先要明确:数组名虽然会隐式转换为首元素地址,但转换后的指针类型和你直接定义的int*完全不同。
看你的代码:
int vec[10][10] = { 1, 2, 3, 4 }; int *v = vec;
这里vec是int[10][10]类型的二维数组,当它隐式转换为指针时,得到的是指向长度为10的int数组的指针(即int (*)[10]),而不是int*。你强行把它赋值给int* v,相当于丢失了数组的维度类型信息。
再看下标访问的本质:a[b]等价于*(a + b),那v[1][1]展开就是*( *(v + 1) + 1 ):
- 对于原数组
vec:vec+1是跳过10个int(一整行),指向第1行的起始地址;*(vec+1)是第1行的数组名,又会转成int*指向该行第一个元素;最后*(...+1)就是取第1行第1列的元素,完全合法。 - 对于
int* v:v+1是跳过1个int,指向vec[0][1];*(v+1)是取出这个位置的int值(也就是2);接下来*(2 + 1)相当于把整数2当成内存地址去取值,这显然是非法的——要么编译报错,要么运行时触发内存访问错误。
这就是为什么二者指向同一地址,但访问行为完全不同:指针的类型决定了指针运算的步长,以及解引用后的结果类型,光地址值相同没用。
关于int (*v)[N]的理解是否正确?
你的理解完全正确!按照C语言的右左结合规则解析:
- 先看括号内的
(*v):说明v是一个指针; - 再看后面的
[N]:说明这个指针指向的是一个包含N个int元素的数组; - 最前面的
int:说明数组里的元素是int类型。
所以int (*v)[N]就是指向长度为N的int数组的指针,用它接收二维数组vec时,类型完全匹配。此时v[1][1]的访问逻辑和原数组完全一致:v+1跳过一整行(N个int),*(v+1)得到该行的数组,再转成int*后访问下标1的元素。
内容的提问来源于stack exchange,提问作者ATpaul
相关产品推荐
相关产品推荐

