C 语言入门学习Day08:字符数组与字符串全解 + 二维整型数组核心知识点

📅 2026/7/29 5:03:54 👁️ 阅读次数 📝 编程学习
C 语言入门学习Day08:字符数组与字符串全解 + 二维整型数组核心知识点

文章目录

  • 前言
  • 一、一维字符型数组:字符串的底层载体
    • 1. 核心特性
    • 2. 字符数组的定义
    • 3. 数组元素的访问
    • 4. 字符数组的存储
    • 5. 字符数组的初始化
      • (1)全部初始化
      • (2)局部初始化
      • (3)默认初始化(不指定长度)
    • 6. 字符串的打印输出
      • (1)printf + %s
      • (2)puts 函数
    • 7. 字符串的输入接收
      • (1)scanf + %s
      • (2)gets 函数
    • 8. 字符串常见操作
      • (1)字符串长度统计
      • (2)字符串拷贝
      • (3)字符串拼接
      • (4)字符串比较
  • 二、二维整型数组
    • 1. 数组定义
    • 2. 数组元素访问
    • 3. 数组的存储
    • 4. 数组的本质理解
    • 5. 二维数组的初始化
      • (1)全部初始化
      • (2)局部初始化
      • (3)默认初始化(省略行数)
  • 今日学习总结
    • 1. 核心知识梳理
    • 2. 踩坑心得

前言

今天是 C 语言学习的第八天,核心内容围绕字符数组与字符串操作二维整型数组展开。C 语言没有原生的字符串类型,所有字符串的存储、遍历与修改都依赖字符数组实现,这是后续 C 语言字符串处理、指针操作的核心基础;同时我们也从一维数组延伸到二维数组,学习其定义、存储规则与初始化语法。

一、一维字符型数组:字符串的底层载体

1. 核心特性

C 语言中没有专门的字符串类型,字符串的存储与操作全部通过字符型数组实现。 一个合法的 C 语言字符串,本质是一段连续的字符内存,并且必须以转义字符'\0'作为结束标志。

2. 字符数组的定义

语法格式:

数据类型 数组名[元素个数];

示例:

char str[20]; // 定义一个可存放20个char类型元素的数组

注意规则:

  • 元素个数必须是常量,不能用变量指定数组长度
  • 数组空间必须足够,要预留 1 个字节存放字符串结束标志'\0'

3. 数组元素的访问

通过下标访问数组元素,下标从 0 开始计数,例如str[0]str[1]str[19]

通用数组长度计算公式(所有类型数组通用):

int len = sizeof(数组名) / sizeof(数组名[0]);

4. 字符数组的存储

  • 字符数组所占总空间大小 = 数组元素个数 × char 类型大小(1 字节),因此 char 数组的sizeof数值等于元素个数
  • 内存在下标维度上连续存储,'\0'是判断字符串结尾的唯一依据

5. 字符数组的初始化

⚠️ 重要概念:初始化 ≠ 赋值,初始化是在数组定义时给初值,赋值是定义后修改内容。

(1)全部初始化

三种写法完全等价,都会自动包含结尾'\0'

char str[6] = {'h', 'e', 'l', 'l', 'o', '\0'}; char str[6] = {"hello"}; char str[6] = "hello";
(2)局部初始化

未显式赋值的元素,系统自动初始化为 0(即'\0'):

char str[6] = {'h', 'e', 'l'}; char str[6] = {"hel"}; char str[6] = "hel"; char str[6] = {0}; // 所有元素全部初始化为0

★ 易混淆概念辨析(高频易错点):

符号含义ASCII 值作用
数值 0整数 00等价于'\0',可作字符串结束符
'\0'转义字符0字符串专属结束标志
'0'字符 048普通可打印字符,无结束作用
(3)默认初始化(不指定长度)

数组长度由初始化内容自动确定:

char str[] = {'h', 'e', 'l', '\0'}; char str[] = {"hel"}; char str[] = "hel";

6. 字符串的打印输出

(1)printf+%s
char str[20] = "hello world"; printf("str = %s\n", str);

规则:从数组首地址开始打印,直到遇到'\0'停止。

(2)puts函数
char str[20] = "hello world"; puts(str);

特点:输出字符串后自动追加一个换行符'\n',无需手动写\n

7. 字符串的输入接收

(1)scanf+%s
char str[32] = {0}; scanf("%s", str);

注意:

  • %s遇到空格、回车、制表符就会停止读取,无法读取带空格的字符串
  • 数组名前面不需要加&
(2)gets函数
char str[32] = {0}; gets(str);

特点:可以读取带空格的字符串,遇到回车停止。

8. 字符串常见操作

所有字符串库函数均需引入头文件<string.h>

(1)字符串长度统计

库函数:strlen

功能:统计从首地址到'\0'之间的有效字符个数,不包含'\0'

char str[32] = "hello"; int len = strlen(str); // len = 5

★ 高频易错对比:

  • strlen:统计字符串有效长度,遇到'\0'结束,和数组总大小无关
  • sizeof:计算数组占用的总内存空间大小,和字符串内容无关
(2)字符串拷贝

库函数:strcpy

char str[32] = {0}; strcpy(str, "hello world");

注意:目标数组空间必须足够容纳源字符串(含'\0'),否则会发生内存越界。

(3)字符串拼接

库函数:strcat

char str1[32] = "hello"; char str2[32] = "world"; strcat(str1, str2); // 结果:str1 = "helloworld"

注意:目标数组必须有足够的剩余空间,容纳拼接后的完整字符串 + 结束符。

(4)字符串比较

库函数:strcmp

int ret = strcmp(str1, str2);

返回值规则:

  • 等于 0:两个字符串完全相等
  • 大于 0:第一个字符串 > 第二个字符串
  • 小于 0:第一个字符串 < 第二个字符串

比较规则:从左到右逐个字符按 ASCII 码比较,出现不同字符时立即得出结果,和字符串总长度无关。

二、二维整型数组

1. 数组定义

语法格式:

数据类型 数组名[行数][列数];

示例:

int a[2][3]; // 定义2行3列的整型数组

规则:行数、列数都必须是常量表达式。

2. 数组元素访问

语法:数组名[行下标][列下标]下标从 0 开始,行下标范围:0 ~ 行数-1,列下标范围:0 ~ 列数-1

例如a[0][0]表示第 0 行第 0 列的元素,a[1][2]表示第 1 行第 2 列的元素。

3. 数组的存储

  • 总空间大小 = 数据类型大小 × 行数 × 列数
  • 存储规则:逐行连续存储,先存第 0 行的所有列,再存第 1 行,依次类推,整体在内存中是连续的线性空间。

4. 数组的本质理解

二维数组可以理解为「元素是一维数组的一维数组」;以此类推,N 维数组可以看作由 N-1 维数组构成的一维数组。

5. 二维数组的初始化

(1)全部初始化
// 平铺写法 int a[2][3] = {1, 2, 3, 4, 5, 6}; // 按行分组写法(结构更清晰,推荐) int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
(2)局部初始化

未显式赋值的元素自动补 0:

int a[2][3] = {1, 2, 3, 4}; int a[2][3] = {{1, 2}, {3}}; int a[2][3] = {0}; // 所有元素初始化为0 int a[2][3] = {{0}}; // 所有元素初始化为0
(3)默认初始化(省略行数)
int a[][3] = {1, 2, 3, 4, 5, 6}; int a[][3] = {1, 2, 3, 4}; int a[][3] = {{1, 2}, {3}};

★ 核心规则:二维数组初始化时,行数可以省略,列数绝对不能省略,系统会根据总元素数和列数自动计算行数。


今日学习总结

1. 核心知识梳理

  1. 字符数组是 C 语言字符串的底层载体,'\0'是字符串的核心标志,所有字符串操作都依赖它判断结尾,这是字符串最核心的本质。
  2. 严格区分sizeofstrlen:前者计算数组总内存空间,后者统计字符串有效字符数,二者概念完全不同,不能混用。
  3. 二维数组按行连续存储,初始化时「行可省、列不可省」是固定语法规则。
  4. 字符串库函数(strlen/strcpy/strcat/strcmp)都依赖<string.h>头文件,使用时必须关注目标空间大小,防止内存越界。

2. 踩坑心得

手写字符串操作时,最容易忽略两个细节:

① 任何拷贝、拼接操作结束后,必须手动给字符串追加'\0'

② 输出字符串时传入数组首地址即可,不要用单个元素作为%s的参数;