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 | 整数 0 | 0 | 等价于'\0',可作字符串结束符 |
'\0' | 转义字符 | 0 | 字符串专属结束标志 |
'0' | 字符 0 | 48 | 普通可打印字符,无结束作用 |
(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. 核心知识梳理
- 字符数组是 C 语言字符串的底层载体,
'\0'是字符串的核心标志,所有字符串操作都依赖它判断结尾,这是字符串最核心的本质。 - 严格区分
sizeof和strlen:前者计算数组总内存空间,后者统计字符串有效字符数,二者概念完全不同,不能混用。 - 二维数组按行连续存储,初始化时「行可省、列不可省」是固定语法规则。
- 字符串库函数(
strlen/strcpy/strcat/strcmp)都依赖<string.h>头文件,使用时必须关注目标空间大小,防止内存越界。
2. 踩坑心得
手写字符串操作时,最容易忽略两个细节:
① 任何拷贝、拼接操作结束后,必须手动给字符串追加'\0'
② 输出字符串时传入数组首地址即可,不要用单个元素作为%s的参数;