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]; - 数组指针

含义

这是一个指向数组的指针,指向一个包含 Nchar 元素的数组。

内存布局

  • 指针本身占用 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]; - 二维数组

含义

这是一个二维字符数组,包含 NM 列的 char 元素。

内存布局

  • 整个数组占用 N * M * sizeof(char) 的连续内存空间
  • 按行优先顺序存储
  • 可以看作是一个包含 N 个元素的数组,每个元素是一个包含 Mchar 的数组

特点

  • 内存是连续的,固定大小
  • 可以通过双重索引访问元素: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=5M=10,在32位系统上:

  • char * array[5];:占用 5 * 4 = 20 字节(存储5个指针)
  • char (* array)[5];:占用 4 字节(存储一个指针)
  • char array[5][10];:占用 5 * 10 = 50 字节(存储50个char)

使用场景

  1. 指针数组:适用于需要存储多个不同长度字符串的场景,如命令行参数处理。
  2. 数组指针:适用于需要在函数间传递二维数组或处理多维数组的场景。
  3. 二维数组:适用于需要存储固定大小字符串集合的场景,如固定格式的表格数据。

注意事项

  • 指针数组中的每个指针需要单独分配内存(或指向已有的内存)
  • 数组指针需要指向一个已存在的数组
  • 二维数组在函数参数传递时会退化为指向首元素的指针

希望这个分析能帮助你理解这四种 char 类型声明的区别和应用场景!

posted @ 2026-03-21 21:02  limh991  阅读(18)  评论(0)    收藏  举报