8. 指针数组:指针数组的定义与使用、指针数组与二维数组的对比、命令行参数argv
指针数组,这个名字听起来有点绕。说白了,就是一个数组,里面每个元素都是指针。嗯,就是这么简单。
我刚开始学C语言那会儿,总觉得指针数组和二维数组是一回事。后来在项目里踩了坑,才真正搞明白它们的区别。今天咱们就把这个知识点彻底讲透。
8.1 指针数组的定义与使用
先看定义。指针数组的语法是这样的:
类型名 *数组名[数组大小];
注意,是 *数组名[大小],不是 (*数组名)[大小]。前者是指针数组,后者是数组指针。这两个东西完全不一样,我见过不少同事在这上面翻车。
举个例子:
char *str_arr[3]; // 一个包含3个char*指针的数组
每个元素都能指向一个字符串。你可以这样初始化:
char *str_arr[3] = {
"Hello",
"World",
"Pointer"
};
这时候,str_arr[0] 指向 "Hello" 的首地址,str_arr[1] 指向 "World" 的首地址,以此类推。
我在项目中经常用指针数组来处理菜单选项。比如一个嵌入式设备的LCD菜单:
char *menu_items[] = {
"1. 系统设置",
"2. 参数校准",
"3. 数据查看",
"4. 固件升级",
"5. 退出"
};
这样写的好处是什么?每个字符串的长度可以不一样,内存利用率高。而且增删菜单项特别方便,改一下数组就行。
8.2 指针数组与二维数组的对比
这两个东西,初学者特别容易搞混。咱们来做个对比。
先看二维数组:
char arr2d[3][10] = {
"Hello",
"World",
"Pointer"
};
再看指针数组:
char *arrptr[3] = {
"Hello",
"World",
"Pointer"
};
表面上看,用法差不多。但内存布局完全不同。
二维数组在内存中是连续的一块空间。3行10列,总共30个字节,整整齐齐排在一起。每个字符串最多只能有9个字符(留一个给'\0')。
指针数组呢?数组本身是连续的,但每个指针指向的字符串可以分散在内存的不同位置。字符串长度也可以不一样。
我画个图帮你理解:
看到区别了吧?二维数组是"方方正正"的一块内存,指针数组是"散装"的。
咱们用表格对比一下:
| 对比项 | 二维数组 | 指针数组 |
|---|---|---|
| 内存布局 | 连续,固定大小 | 数组连续,数据可分散 |
| 字符串长度 | 每行固定长度 | 每个字符串可不同长度 |
| 内存利用率 | 可能有浪费(短字符串占满整行) | 利用率高 |
| 修改字符串内容 | 可以直接修改 | 指向常量时不能修改 |
| 访问速度 | 稍快(连续内存,缓存友好) | 稍慢(需要间接寻址) |
8.3 命令行参数 argv
说到指针数组,最经典的应用就是 main 函数的参数 argv 了。
int main(int argc, char *argv[])
argc 是参数个数,argv 就是一个指针数组。每个元素指向一个命令行参数字符串。
举个例子,假设你的程序叫 test,在命令行这样运行:
./test hello world 123
那么:
- argc = 4
- argv[0] = "./test"
- argv[1] = "hello"
- argv[2] = "world"
- argv[3] = "123"
- argv[4] = NULL(最后一个元素是空指针)
我曾经在一个嵌入式项目中,用 argv 来传递配置参数。比如:
./sensor_app --mode=fast --interval=100 --output=uart
解析起来也很简单:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--mode=fast") == 0) {
printf("设置快速模式\n");
} else if (strcmp(argv[i], "--interval=100") == 0) {
printf("采样间隔设为100ms\n");
} else if (strcmp(argv[i], "--output=uart") == 0) {
printf("输出到串口\n");
} else {
printf("未知参数: %s\n", argv[i]);
}
}
return 0;
}
你想想看,如果没有指针数组,处理这种不定长的命令行参数得多麻烦?
- 指针数组是"数组元素是指针"的数组
- 与二维数组的区别在于内存布局和灵活性
- argv 是指针数组的典型应用
- 指针数组适合处理长度不等的字符串集合
嗯,指针数组这块内容就讲到这里。记住一点:指针数组和二维数组各有适用场景,选哪个要看你的具体需求。如果字符串长度固定,用二维数组;如果长度不固定,或者需要频繁增删,指针数组更合适。
我曾经在一个数据采集项目里,因为用了二维数组存储传感器名称,结果有个名称超长导致程序崩溃。后来改成指针数组,问题就解决了。所以,选对工具很重要。
公众号:蓝海资料掘金营,微信deep3321