二维数组指针算术访问:如何获取a[0][1]与a[1][1]的值?
二维数组的指针算术访问方案
错误原因解析
你写的代码出现段错误,核心问题是类型不匹配:
- 二维数组
int a[2][2]在内存中是连续存储的,布局为1, 2, 3, 4依次排列。 &a[0][0]的实际类型是int*(指向单个int的指针),但你把它赋值给了int**类型的变量p(指向指针的指针)。- 执行
**p时,程序会先把a[0][0]的值(1)当作一个内存地址去解引用,这显然是非法的内存访问,直接触发段错误。
你之前用*(p+1)得到3是巧合:64位系统中int**的大小是8字节,p+1会跳过8字节(即2个int的空间),正好指向a[1][0]的地址,解引用一次得到3,但这种写法属于未定义行为,不能依赖。
正确的指针算术用法
方案1:使用指向一维数组的指针(匹配二维数组类型)
二维数组a[2][2]可以看作是由2个int[2]类型的一维数组组成的,因此可以用指向int[2]的指针来访问:
#include <stdio.h> int main() { int a[2][2] = {{1,2},{3,4}}; int (*p)[2] = a; // p指向包含2个int的一维数组 // 获取a[0][1] printf("a[0][1] = %d\n", (*p)[1]); // 或 p[0][1] // 获取a[1][1] printf("a[1][1] = %d\n", (*(p+1))[1]); // 或 p[1][1] return 0; }
这里p+1会跳过一整个int[2]数组(8字节,假设int为4字节),直接指向a[1]的起始地址,再通过[1]访问第二个元素。
方案2:使用int*指针直接指向数组首元素
因为二维数组在内存中是连续的,也可以用普通的int*指针指向数组的首元素,通过偏移量访问:
#include <stdio.h> int main() { int a[2][2] = {{1,2},{3,4}}; int* p = &a[0][0]; // 或直接写 int* p = *a; // 获取a[0][1]:首元素偏移1个int printf("a[0][1] = %d\n", *(p + 1)); // 获取a[1][1]:首元素偏移3个int(0→1→2→3) printf("a[1][1] = %d\n", *(p + 3)); // 或者用行列计算:偏移量 = 行号*列数 + 列号 → 1*2+1=3 printf("a[1][1] = %d\n", *(p + 1*2 + 1)); return 0; }
这种方式利用了数组内存连续的特性,通过计算元素在数组中的线性偏移量来访问。
内容的提问来源于stack exchange,提问作者Daniel Muñoz
相关产品推荐
相关产品推荐

