C语言指针疑问:**(p2[1][0] + 1)为何输出14且指针加1跳行?
为什么这段C语言代码的printf输出是14?
先明确核心类型定义
先理清代码里的两个typedef,这是理解指针运算的关键:
#define N 3 typedef int(*MyType1)[N]; // MyType1 是指向长度为3的int数组的指针 typedef int(*MyType2)[N][N]; // MyType2 是指向3x3二维int数组的指针
一步步拆解关键表达式 **(p2[1][0] + 1)
我们逐段分析这个表达式的含义:
p2[1]是什么?p2是MyType2类型的数组,每个元素都是指向3x3二维数组的指针。其中p2[1] = &m1,也就是p2[1]是指向整个m1二维数组的指针,类型为int(*)[3][3]。p2[1][0]是什么?
C语言中数组下标运算a[b]等价于*(a + b),所以p2[1][0] = *(p2[1] + 0) = *&m1 = m1。
这里m1是3x3二维数组的数组名,在表达式中会隐式转换为指向其第一行的指针(因为二维数组的元素是一维数组),类型是int(*)[3](也就是MyType1),指向的是m1[0](即第一行的数组)。p2[1][0] + 1为什么会跳一行?
指针加法的偏移量由指针指向的类型大小决定:p2[1][0]是指向长度为3的int数组的指针,所以加1时,偏移量是整个一维数组的大小(3 * sizeof(int)),而不是单个int的大小。
因此p2[1][0] + 1会从指向m1[0](第一行)跳转到指向m1[1](第二行)。两次解引用
**(...)的结果- 第一次解引用
*(p2[1][0] + 1):得到m1[1]这个一维数组,数组名再次转换为指向其第一个元素的指针,也就是&m1[1][0]。 - 第二次解引用
**(...):取这个指针指向的元素,也就是m1[1][0],对应的值就是14。
- 第一次解引用
纠正你的误解
你认为&m1[0]是第一个元素21的地址,这是错误的:
m1[0]是长度为3的一维数组,&m1[0]的类型是int(*)[3],是指向这个一维数组的指针,不是指向单个int的指针。- 指向21的正确地址是
&m1[0][0](直接取第一个元素的地址),或者m1[0](数组名隐式转换为指向首元素的指针)。 - 正因为
&m1[0]是指向一维数组的指针,所以它加1时会跳过整个一维数组(3个int),直接跳到下一行,这就是你看到“每次加1访问n+3位置”的原因。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

