双重指针和数组指针是C语言中两种不同的多级指针概念,它们在内存布局、使用方式和应用场景上有显著区别。
1. 双重指针(Pointer to Pointer)
定义:指向指针的指针,存储的是另一个指针变量的地址。
特点:
- 常用于动态内存分配(如动态二维数组)
- 可以指向不同长度的指针数组
- 指针算术运算以指针大小为单位(通常4/8字节)
声明语法:
数据类型 **指针变量名;
示例1:动态二维数组
#include <stdio.h>
#include <stdlib.h>
int main() {
int rows = 3, cols = 4;
int **matrix = (int **)malloc(rows * sizeof(int *));
for(int i = 0; i < rows; i++) {
matrix[i] = (int *)malloc(cols * sizeof(int));
for(int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
}
}
// 访问元素
printf("matrix[1][2] = %d\n", matrix[1][2]); // 输出6
// 释放内存
for(int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
return 0;
}
2. 数组指针(Pointer to Array)
定义:指向整个数组的指针,存储的是数组的首地址。
特点:
- 常用于处理固定大小的多维数组
- 指针算术运算以整个数组大小为单位
- 类型信息中包含数组长度
声明语法:
数据类型 (*指针变量名)[数组长度];
示例2:静态二维数组处理
#include <stdio.h>
void print_matrix(int (*arr)[4], int rows) {
for(int i = 0; i < rows; i++) {
for(int j = 0; j < 4; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main() {
int matrix[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};
int (*ptr)[4] = matrix; // 指向包含4个int的数组的指针
// 访问元素
printf("ptr[1][2] = %d\n", ptr[1][2]); // 输出6
// 作为函数参数传递
print_matrix(matrix, 3);
return 0;
}
关键区别总结
特性 |
双重指针 |
数组指针 |
声明方式 |
|
|
指向内容 |
指向指针 |
指向整个数组 |
内存布局 |
通常动态分配,内存可能不连续 |
通常静态分配,单个连续的内存块 |
算术运算 |
以指针大小为单位。pp++移动一个指针的大小 |
以数组大小为单位。pa++移动整个数组的大小 |
灵活性 |
可以指向不同长度的数组 |
必须匹配声明的数组长度 |
常见用途 |
动态二维数组、字符串数组,动态数据结构(如稀疏矩阵等) |
静态多维数组、函数参数。固定大小的多维数组处理 |
理解这些区别对于正确选择和使用这两种指针类型非常重要。