/* null pointer definition */
#define RT_NULL 0
指针数组(const char *net_modules[])
-
内存布局:
数组中每个元素是一个 指针,指向字符串常量(如"UMA503")。字符串存储在程序的只读数据区,指针数组本身存储这些地址。const char *net_modules[] = {
"UMA503", // 指针指向常量字符串
"YM310",
"ML307",
RT_NULL // 哨兵值(空指针)
}; -
特点:
-
支持 不同长度的字符串(如 "UMA503" 和 "YM310" 长度不同)。
-
通过
RT_NULL标记数组结束。 -
内存占用更高效(指针大小固定,通常为4或8字节,字符串本身共享常量区)。
-
2. 普通数组(const char net_modules[])
-
内存布局:
若尝试直接定义为普通数组,语法上需要明确指定维度(如二维数组),且所有字符串必须连续存储:// 需要指定每行长度(按最长字符串定义)
const char net_modules[][7] = {
"UMA503",
"YM310",
"ML307",
"" // 空字符串作为结束标志
}; -
特点:
-
所有字符串必须等长(需预定义列数,如
[7])。 -
空字符串
""替代RT_NULL作为结束标志。 -
内存连续存储,可能浪费空间(短字符串填充空白字符)。
-
二、为何不能直接替换?
1. 类型不兼容
-
指针数组:
元素类型为const char*,每个元素是地址。 -
普通数组:
若定义为const char net_modules[],它是一个一维字符数组,而非字符串数组。要表示多个字符串,必须使用二维数组const char net_modules[][N],其中N是固定列数。
三、两种方案的优缺点
1. 指针数组(const char *net_modules[])
-
优点:
-
支持变长字符串,内存高效。
-
哨兵值
RT_NULL简洁直观。 -
扩展性强,新增模块无需调整维度。
-
-
缺点:
-
字符串存储在只读区,不可修改(符合设计预期)。
-
2. 普通二维数组(const char net_modules[][N])
-
优点:
-
数据连续存储,某些场景下缓存更友好。
-
可直接修改内容(若未使用
const)。
-
-
缺点:
-
内存浪费(需按最长字符串定义列数)。
-
必须预定义固定列数,灵活性差。
-
需额外处理结束标志(如空字符串)。
-
四、如何选择?
适用场景
-
指针数组:
-
需要支持不同长度字符串。
-
字符串内容固定(如硬件型号名称)。
-
需通过指针空值(
RT_NULL)快速终止遍历。
-
-
普通二维数组:
-
字符串长度相同或接近。
-
需要频繁修改字符串内容(但此时不应使用
const)。 -
内存连续访问性能关键(如嵌入式系统无缓存)。
-
五、示例对比
指针数组实现
const char *net_modules[] = {
"UMA503",
"YM310",
"ML307",
RT_NULL // 结束标志
};
// 遍历
for (int i = 0; net_modules[i] != RT_NULL; i++) {
printf("Module: %s\n", net_modules[i]);
}
普通二维数组实现
const char net_modules[][7] = {
"UMA503",
"YM310",
"ML307",
"" // 结束标志(空字符串)
};
// 遍历
for (int i = 0; strcmp(net_modules[i], "") != 0; i++) {
printf("Module: %s\n", net_modules[i]);
}
总结
-
不能直接替换:
const char *net_modules[]和const char net_modules[]类型不同,用途不同。 -
替代方案:若必须使用普通数组,需改为二维数组
const char net_modules[][N],并处理长度和结束标志。 -
推荐选择:在表示字符串列表时,指针数组更灵活高效,是更常见的设计。

361

被折叠的 条评论
为什么被折叠?



