C 语言指针与多维数组
更新时间:2026-08-26。本文是
languages/c/主题高手层的骨架文档(占位),完整展开将在后续批次补齐。
本文要回答的问题
- 二维数组在内存里是"一行接一行"吗?
int *p[3]和int (*p)[3]有什么不同?- 怎么动态分配一个二维数组?三种写法差在哪?
一、连续 vs 分段
| 形式 | 内存布局 | 适用 |
|---|---|---|
int a[3][4] | 连续 12 个 int,行内元素相邻 | 固定维度、局部性好 |
int *p[3](指针数组) | 3 个指针,各自指向一段 | 每行长度不同 |
int **pp(动态) | 指针的指针,逐行 malloc | 完全动态 |
int a[3][4] 是一维连续存储的"数组的数组"——a[1] 紧跟在 a[0] 后,遍历时缓存友好;指针数组和动态二维则是分段布局,每行可能不在同一页。
二、声明辨析
c
int *p[3]; /* 指针数组:3 个 int* */
int (*p)[3]; /* 数组指针:指向"含 3 个 int"的数组 */
int **pp; /* 二级指针:常用于动态二维 */理解优先级:[] 比 * 结合更紧,所以 int *p[3] 先看 p[3] 是数组、元素是 int*。
三、动态分配三种写法
- 连续一次分配:
malloc(rows * cols * sizeof(int)),用a[r*cols+c]访问——最快、最省。 - 指针数组逐行分配:
malloc每行,a[r][c]自然语法——行变长方便,但多 N 次 malloc、局部性差。 - 二级指针:
int **a = malloc(rows * sizeof(int*))再逐行——与 2 类似。
函数传参:固定列数用 int a[][4];动态用 int **a 或 int *a + 手动下标。
四、与入门层的衔接
一句话总结
"二维"只是语法糖:固定二维是连续内存、指针数组是分段内存,动态分配选"一次大 malloc + 手动下标"既快又省,函数传参看清声明优先级。
本文为骨架文档:核心结构已就位,示例代码与实测数据将在后续批次补齐。