C语言拾遗
四种 char 类型声明的详细分析
1. char * array[N]; - 指针数组
含义
这是一个指针数组,包含 N 个指向 char 类型的指针元素。
内存布局
- 整个数组占用
N * sizeof(char*)的内存空间 - 每个元素都是一个独立的
char*指针 - 每个指针可以指向不同长度的字符串
特点
- 元素是指针,可以指向不同的内存地址
- 数组长度固定为
N,但每个指针指向的字符串长度可变 - 可以通过索引访问每个指针,再通过指针访问字符串
示例
char * array[3];
array[0] = "Hello";
array[1] = "World";
array[2] = "C Programming";
2. char (* array)[N]; - 数组指针
含义
这是一个指向数组的指针,指向一个包含 N 个 char 元素的数组。
内存布局
- 指针本身占用
sizeof(char(*)[N])的内存空间(通常是4或8字节) - 指针指向的是一个连续的内存块,大小为
N * sizeof(char)
特点
- 指针指向的是整个数组,而不是单个元素
- 数组的大小
N是固定的 - 解引用指针会得到整个数组
示例
char arr[5] = "test";
char (*array)[5] = &arr;
3. char *(array[N]) - 指针数组(与第一种等价)
含义
这与第一种声明 char * array[N]; 完全等价,是一个指针数组。
解释
括号在这里不起实际作用,因为数组下标运算符 [] 的优先级高于解引用运算符 *,所以即使加上括号,仍然是先计算 array[N],然后再对结果进行 * 操作。
4. char array[N][M]; - 二维数组
含义
这是一个二维字符数组,包含 N 行 M 列的 char 元素。
内存布局
- 整个数组占用
N * M * sizeof(char)的连续内存空间 - 按行优先顺序存储
- 可以看作是一个包含
N个元素的数组,每个元素是一个包含M个char的数组
特点
- 内存是连续的,固定大小
- 可以通过双重索引访问元素:
array[i][j] - 常用于存储固定大小的字符串集合
示例
char array[3][10] = {
"Hello",
"World",
"C"
};
核心区别对比
| 类型 | 声明 | 本质 | 内存布局 | 主要用途 |
|---|---|---|---|---|
| 指针数组 | char * array[N]; |
N个char*指针 | 不连续,每个元素是指针 | 存储不同长度的字符串 |
| 数组指针 | char (* array)[N]; |
指向N个char的数组的指针 | 连续,指针指向数组 | 指向固定大小的数组 |
| 二维数组 | char array[N][M]; |
N行M列的char数组 | 连续,按行存储 | 存储固定大小的字符串集合 |
内存占用对比
假设 N=5,M=10,在32位系统上:
char * array[5];:占用5 * 4 = 20字节(存储5个指针)char (* array)[5];:占用4字节(存储一个指针)char array[5][10];:占用5 * 10 = 50字节(存储50个char)
使用场景
- 指针数组:适用于需要存储多个不同长度字符串的场景,如命令行参数处理。
- 数组指针:适用于需要在函数间传递二维数组或处理多维数组的场景。
- 二维数组:适用于需要存储固定大小字符串集合的场景,如固定格式的表格数据。
注意事项
- 指针数组中的每个指针需要单独分配内存(或指向已有的内存)
- 数组指针需要指向一个已存在的数组
- 二维数组在函数参数传递时会退化为指向首元素的指针
希望这个分析能帮助你理解这四种 char 类型声明的区别和应用场景!

浙公网安备 33010602011771号