C 语言指针数组
外观
C语言指针数组[编辑 | 编辑源代码]
指针数组是C语言中一种特殊的数组类型,其元素均为指针。这种数据结构在需要管理多个指针时非常有用,特别是在处理字符串数组、动态内存分配和多维数组模拟等场景中。
基本概念[编辑 | 编辑源代码]
指针数组的定义形式为:
数据类型 *数组名[数组长度];
其中:
- 数据类型:指针所指向的数据类型
- 数组名:指针数组的名称
- 数组长度:数组中指针的数量
基本示例[编辑 | 编辑源代码]
下面是一个简单的指针数组示例,存储多个整数的地址:
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 30;
int *ptr_arr[3]; // 声明一个包含3个int指针的数组
ptr_arr[0] = &a;
ptr_arr[1] = &b;
ptr_arr[2] = &c;
for(int i = 0; i < 3; i++) {
printf("ptr_arr[%d] = %p, *ptr_arr[%d] = %d\n",
i, ptr_arr[i], i, *ptr_arr[i]);
}
return 0;
}
输出示例:
ptr_arr[0] = 0x7ffd4a3b5a1c, *ptr_arr[0] = 10 ptr_arr[1] = 0x7ffd4a3b5a20, *ptr_arr[1] = 20 ptr_arr[2] = 0x7ffd4a3b5a24, *ptr_arr[2] = 30
字符串指针数组[编辑 | 编辑源代码]
指针数组最常见的应用之一是存储字符串,因为字符串本身就是字符数组的指针:
#include <stdio.h>
int main() {
char *names[] = {"Alice", "Bob", "Charlie", "David"};
int count = sizeof(names)/sizeof(names[0]);
for(int i = 0; i < count; i++) {
printf("Name %d: %s\n", i+1, names[i]);
}
return 0;
}
输出:
Name 1: Alice Name 2: Bob Name 3: Charlie Name 4: David
指针数组与二维数组的区别[编辑 | 编辑源代码]
虽然指针数组可以模拟二维数组的行为,但它们有本质区别:
特性 | 指针数组 | 二维数组 |
---|---|---|
内存布局 | 不连续 | 连续 |
每行长度 | 可以不同 | 必须相同 |
内存分配 | 可以动态分配 | 通常是静态分配 |
动态内存分配[编辑 | 编辑源代码]
指针数组常与动态内存分配结合使用:
#include <stdio.h>
#include <stdlib.h>
int main() {
int **matrix;
int rows = 3, cols = 4;
// 分配行指针
matrix = (int **)malloc(rows * sizeof(int *));
// 为每行分配列
for(int i = 0; i < rows; i++) {
matrix[i] = (int *)malloc(cols * sizeof(int));
}
// 初始化并打印
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
// 释放内存
for(int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
return 0;
}
输出:
0 1 2 3 4 5 6 7 8 9 10 11
高级应用:函数指针数组[编辑 | 编辑源代码]
指针数组也可以存储函数指针,这在实现状态机或回调机制时非常有用:
#include <stdio.h>
void func1() { printf("Function 1 called\n"); }
void func2() { printf("Function 2 called\n"); }
void func3() { printf("Function 3 called\n"); }
int main() {
void (*func_ptr_arr[])() = {func1, func2, func3};
int choice;
printf("Enter a number (1-3): ");
scanf("%d", &choice);
if(choice >= 1 && choice <= 3) {
func_ptr_arr[choice-1]();
} else {
printf("Invalid choice\n");
}
return 0;
}
数学表示[编辑 | 编辑源代码]
指针数组可以表示为: 其中每个都是一个指针,满足: 是目标数据类型。
实际应用场景[编辑 | 编辑源代码]
1. 命令行参数处理:main(int argc, char *argv[])
中的argv
就是一个字符串指针数组
2. 菜单系统实现:存储菜单项及其对应的处理函数
3. 多态模拟:在C中模拟面向对象的多态行为
4. 稀疏矩阵存储:只存储非零元素的指针
常见错误与注意事项[编辑 | 编辑源代码]
1. 未初始化的指针数组元素可能导致段错误
2. 混淆指针数组和数组指针(int (*arr)[10]
vs int *arr[10]
)
3. 内存泄漏:动态分配的指针数组需要逐元素释放
4. 越界访问:与其他数组一样,指针数组也有边界限制
性能考虑[编辑 | 编辑源代码]
- 访问时间:与普通数组相同,O(1)随机访问
- 内存开销:需要额外存储指针本身
- 缓存效率:指针间接寻址可能导致缓存不命中
通过理解指针数组的概念和应用,C程序员可以更灵活地处理复杂的数据结构和内存管理任务。