一、让我们一起走进《字符王国》!
🧙♂️ 字符数组(char a[ ])
1、故事开场:字符小士兵排队 🧑🚀🧑🚀🧑🚀
在 C++ 王国里,有很多字符小士兵:
'H' 'e' 'l' 'l' 'o'每一个字符,都住在一个小房间里。
字符数组,就是让这些字符手拉手排成一排的宿舍!
char a[5];📌 含义:
char:每个房间住一个字符a:宿舍名字[5]:一共 5 个房间
2、超级重要的秘密:\0结尾守卫 🚨(⚠️必讲)
字符数组里有一个神秘的守卫:
'\0' (空字符)👮♂️ 它的任务是告诉电脑:
“字符串到这里结束啦!”
👀 举个例子:
char a[] = {'H', 'i', '\0'};这才是一个合法的“字符串”!
更常见的写法(推荐)✨:
char a[] = "Hi";⚠️ 编译器会自动帮你变成:
'H' 'i' '\0'📌结论(一定要牢记):
👉字符数组当字符串用,结尾必须有
'\0'!
3、字符数组 vs 普通数组 🧺
| 项目 | int 数组 | char 字符数组 |
|---|---|---|
| 存什么 | 数字 | 字符 |
| 是否需要结尾标志 | ❌ 不需要 | ✅ 必须'\0' |
| 能直接输出吗 | ❌ | ✅(遇到'\0'停) |
4、字符数组的几种创建方式 🏗️
🧩 方法 1:一个个字符写(不推荐)
char a[4] = {'C', '+', '+', '\0'};🧩 方法 2:字符串形式(⭐最常用)
char a[] = "C++";💡 编译器自动算长度:'C' '+' '+' '\0'→ 共 4 个
5、如何访问字符小士兵?(下标)🔍
char a[] = "Hello";| 下标 | 字符 |
|---|---|
| a[0] | 'H' |
| a[1] | 'e' |
| a[2] | 'l' |
| a[3] | 'l' |
| a[4] | 'o' |
| a[5] | '\0' |
🧪 小实验:
cout << a[1]; // 输出 e6、输出字符数组 📢
方式 1:直接输出(最简单)
cout << a;💡 原理:
👉 一直输出,直到遇到'\0'为止!
方式 2:一个字符一个字符输出
for (int i = 0; a[i] != '\0'; i++) { cout << a[i]; }🧠 这是“字符数组的标准遍历方式”
7、输入字符数组(⚠️重点)✍️
1️⃣ 使用cin
char name[20]; cin >> name;⚠️ 注意:
遇到空格就停!
只能输入一个“单词”
❌ 不能这样写:
cin >> name[100]; // 错误!2️⃣ 使用 cin.getline
#include <iostream> using namespace std; int main() { char sentence[50]; cin.getline(sentence, 50); cout << sentence; return 0; }🧠 输入:
Hello world I love C++📤 输出:
Hello world I love C++3️⃣cin.getline为什么要写“最大长度”? 🏠
📖 故事
书记官问:
“我最多能写几个字?房子多大?”
如果你不告诉他,
他可能会写到别人家里去(💥越界)
char a[20]; cin.getline(a, 20);📌 最多读19 个字符 + '\0'
4️⃣ 旧时代的魔法 ⚠️:gets(⚠️只讲认识)
gets是一个不问房子多大的老魔法师,
非常危险 ⚠️
char a[20]; gets(a); // ❌ 不要用📌现代 C++:禁止使用
8、常用字符数组函数(来自<cstring>)🧰
可以告诉孩子:这是字符数组的“魔法工具箱”
1️⃣strlen—— 数一数有多少字符 📏
#include <cstring> char a[] = "Hello"; cout << strlen(a); // 输出 5⚠️ 不算'\0'!
2️⃣strcpy—— 复制字符串 🪄
char a[20]; char b[] = "Cat"; strcpy(a, b); // 把 b 复制到 a📌 a 里现在是"Cat"
3️⃣strcat—— 拼接字符串 🧩
char a[20] = "Hi "; char b[] = "Tom"; strcat(a, b); // a 变成 "Hi Tom"⚠️ 宿舍要够大!
4️⃣ 拼接高手(限量版)🧩:strncat
拼接工人strcat有时太贪心,strncat说:
“我只拼接指定数量的字符!”
✨ 用法
char a[20] = "Hello "; char b[] = "World!!!"; strncat(a, b, 5);📌 a 变成"Hello World"
5️⃣strcmp—— 比较两个字符串 ⚖️
char a[] = "apple"; char b[] = "banana"; cout << strcmp(a, b);| 返回值 | 含义 |
|---|---|
| 0 | 一样 |
| <0 | a 小 |
| >0 | a 大 |
6️⃣memset(重要!)
⚠️ 虽然不是“字符串专用”,
但字符数组超级常用!
📖 故事
清洁工memset的工作是:
把一整片房间,全部打扫成同一个样子!
char a[10]; memset(a, 0, sizeof(a));📌 全部清零(安全)
再来一个有趣的例子 🎨
✨ 用法
char line[6]; memset(line, '*', 5); line[5] = '\0'; cout << line; // *****9、一个完整小故事程序 🌟
🎒《数数名字几个字母》
#include <iostream> #include <cstring> using namespace std; int main() { char name[20]; cout << "请输入你的名字:"; cin >> name; cout << "你好," << name << "!\n"; cout << "你的名字有 " << strlen(name) << " 个字母。\n"; return 0; }10、给小学生的“三条金规则” 📜
🟢规则 1:
字符数组当字符串用,必须有
'\0'
🟢规则 2:
输出时,遇到
'\0'就停
🟢规则 3:
字符数组是老前辈,
string是新英雄
学会 char[],C++ 才算真入门!
二、 🕳️《字符王国·十大陷阱历险记》
——char 数组常见“坑点”
在字符王国里,很多小程序员第一次冒险,
都会不小心掉进一些“看不见的坑”。
别怕~今天我们一边讲故事,一边把这些坑全部填平!
🕳️ 坑 1:忘记带小尾巴'\0'(最危险!)☠️
📖 故事
有一天,字符小队排队出门,
可队尾的结束守卫'\0'没来!
电脑就以为队伍还没结束,一直往后走……💥
❌ 错误示例
char a[3] = {'c', 'a', 't'}; // 没有 '\0' cout << a; // 可能乱输出✅ 正确做法
char a[4] = {'c', 'a', 't', '\0'};或:
char a[] = "cat";📜童话口诀:
字符串要回家,尾巴不能丢!
🕳️ 坑 2:房子太小,字符挤爆了 🏚️
📖 故事
小猫"Kitty"要住进 4 间小房子,
结果……
忘了给 `'\0' 留房间!
❌ 错误示例
char a[5] = "Kitty"; // 实际需要 6✅ 正确做法
char a[6] = "Kitty";📌规则:
字符数 + 1 = 数组大小
🕳️ 坑 3:用==比较字符串 ⚔️(打错对象)
📖 故事
两个小朋友说:
“我想看看这两个名字是不是一样!”
结果他们用拳头==去比地址……🥴
❌ 错误示例
char a[] = "cat"; char b[] = "cat"; if (a == b) { } // ❌✅ 正确做法
if (strcmp(a, b) == 0) { cout << "一样!"; }📜童话口诀:
字符串比内容,strcmp 出马!
🕳️ 坑 4:cin遇到空格就逃跑 💨
📖 故事
小朋友输入:
Tom Cat
cin只听到Tom,
看到空格就溜走了……
❌ 表现
char name[20]; cin >> name; // 只能读到 Tom📌(这是规则,不是 bug)
✅ 提示孩子
char 数组 + cin = 只能读一个词
🕳️ 坑 5:strcpy太猛,把房子撞坏 💥
📖 故事
复制工人strcpy力气太大,
不看房子大小,直接全搬!
❌ 错误示例
char a[5]; strcpy(a, "elephant"); // 爆了!✅ 正确做法
char a[20]; strcpy(a, "elephant");📜口诀:
先量房子,再搬家具!
🕳️ 坑 6:strncpy忘了补尾巴 🪓
📖 故事
谨慎复制员只复制指定数量,
但他说:
“尾巴你自己补!”
❌ 易错点
char a[5]; strncpy(a, "hello", 5); // 没有 '\0'✅ 正确做法
a[4] = '\0';📌结论:
strncpy不一定帮你加'\0'
🕳️ 坑 7:strlen算错了 📏
📖 故事
有孩子问:
“
"cat"长度不是 4 吗?还有'\0'呢?”
❌ 误解
strlen("cat") == 4 ❌✅ 真相
strlen("cat") == 3📜口诀:
长度不算尾巴!
🕳️ 坑 8:访问到了“禁区房间” 🚫
📖 故事
字符数组只有 5 间房,
却偷偷跑去访问第 6 间……👻
❌ 错误示例
char a[5] = "Hi"; cout << a[10]; // 越界🧠 提醒
下标范围:0 ~ 大小-1
🕳️ 坑 9:memset被当成字符串魔法 🧪
📖 故事
有人想用memset把字符串变成"abc"……
❌ 错误用法
memset(a, 'abc', 3); // ❌✅ 正确理解
memset(a, 'x', 3); // xxx📌memset只能填一个字符
🕳️ 坑 10:忘记#include <cstring>📦
📖 故事
魔法书忘了带,
所有魔法都施不出来……
❌ 错误
strcpy(a, b); // 编译错误✅ 正确
#include <cstring>三、✅《字符数组专项练习 10 题(闯关式)》
🏰 闯关说明
小程序员将踏入字符王国冒险地图,
一共10 关,难度逐步升级:
🌱 前 1–3 关:认识字符数组
🌿 第 4–7 关:操作与函数
🌳 第 8–10 关:综合 + 思维训练
🧩 第 1 关:字符小士兵点名 👮♂️(入门)
📖 故事
老师要点名,请你把名字存进字符数组里,并输出。
✍️ 要求
定义一个字符数组
存入
"Tom"输出这个名字
✅ 参考代码
#include <iostream> using namespace std; int main() { char name[] = "Tom"; cout << name; return 0; }🧠 讲解
"Tom"实际存的是:T o m \0cout << name会一直输出到'\0'
🧩 第 2 关:一个一个走出来 🚶♂️🚶♀️
📖 故事
字符小士兵要一个一个走出城门。
✍️ 要求
用for循环,一个字符一个字符输出"Cat"
✅ 参考代码
#include <iostream> using namespace std; int main() { char a[] = "Cat"; for (int i = 0; a[i] != '\0'; i++) { cout << a[i] << endl; } return 0; }🧠 讲解
判断条件是
a[i] != '\0'这是字符数组的标准遍历方式
🧩 第 3 关:数一数有多少人 📏
📖 故事
国王想知道队伍里有多少个字符。
✍️ 要求
输出"Hello"的长度(不算'\0')
✅ 参考代码
#include <iostream> #include <cstring> using namespace std; int main() { char a[] = "Hello"; cout << strlen(a); return 0; }🧠 讲解
strlen不数'\0'"Hello"→ 5
🧩 第 4 关:名字复制术 🪄
📖 故事
魔法师要把一个名字复制给另一个人。
✍️ 要求
把"Bob"复制到另一个字符数组中,并输出。
✅ 参考代码
#include <iostream> #include <cstring> using namespace std; int main() { char a[10]; char b[] = "Bob"; strcpy(a, b); cout << a; return 0; }🧠 讲解
a的空间要够大strcpy会连'\0'一起复制
🧩 第 5 关:拼接魔法 ✂️➕
📖 故事
把"Hello "和"Tom"拼成一句话。
✍️ 要求
使用strcat
✅ 参考代码
#include <iostream> #include <cstring> using namespace std; int main() { char a[20] = "Hello "; char b[] = "Tom"; strcat(a, b); cout << a; return 0; }🧠 讲解
拼接结果存在第一个数组里
宿舍一定要够大!
🧩 第 6 关:真假裁判 ⚖️
📖 故事
裁判要判断两个名字是否一样。
✍️ 要求
比较"cat"和"cat"
✅ 参考代码
#include <iostream> #include <cstring> using namespace std; int main() { char a[] = "cat"; char b[] = "cat"; if (strcmp(a, b) == 0) { cout << "一样!"; } else { cout << "不一样!"; } return 0; }🧠 讲解
不能用
==strcmp == 0表示完全相同
🧩 第 7 关:寻找失踪的字母 🔍
📖 故事
在"banana"里找字母'n'
✍️ 要求
使用strchr
✅ 参考代码
#include <iostream> #include <cstring> using namespace std; int main() { char s[] = "banana"; if (strchr(s, 'n')) { cout << "找到了!"; } else { cout << "没找到!"; } return 0; }🧠 讲解
找到 → 返回地址
找不到 → 返回
NULL
🧩 第 8 关:清空房间 🧹(重要)
📖 故事
房间要重新使用,先全部清空!
✍️ 要求
用memset把字符数组清零
✅ 参考代码
#include <iostream> #include <cstring> using namespace std; int main() { char a[10]; memset(a, 0, sizeof(a)); cout << "清空完成!"; return 0; }🧠 讲解
0等价于'\0'非常常用的安全操作
🧩 第 9 关:部分复制术 ✂️
📖 故事
只想复制"elephant"的前三个字母。
✍️ 要求
结果应为"ele"
✅ 参考代码
#include <iostream> #include <cstring> using namespace std; int main() { char a[10]; strncpy(a, "elephant", 3); a[3] = '\0'; // 手动补尾巴 cout << a; return 0; }🧠 讲解
strncpy不一定加'\0'必须手动补!
🧩 第 10 关:终极挑战 💎(综合)
📖 故事
请你写一个程序:
1️⃣ 输入一个名字
2️⃣ 输出名字
3️⃣ 输出名字长度
4️⃣ 如果名字是"admin",输出“欢迎管理员”
✅ 参考代码
#include <iostream> #include <cstring> using namespace std; int main() { char name[20]; cin >> name; cout << "你好," << name << endl; cout << "长度:" << strlen(name) << endl; if (strcmp(name, "admin") == 0) { cout << "欢迎管理员!"; } return 0; }🧠 讲解
综合使用:输入 / 输出 / 长度 / 比较
是char 数组阶段的毕业关卡🎓
🏆 闯关总结
🎖️能完成前 5 关:字符数组入门成功
🏅能完成 7 关:已经会用 cstring 魔法
🏆能完成 10关:你已经开始掌握 char 数组了!
四、📝《字符数组竞赛专项测试卷(选择题)》
🎒 适合:初学 C++ 的小学生
🧙♂️ 只考char a[]+<cstring>
📚 目标:检查是否真正掌握字符数组
📜 考试说明
本试卷共15 题,每题只有一个正确答案。
每题 1 分,满分 15 分。
仔细读题,不着急,字符小士兵会帮你!
🧩 一、基础认知关(第 1~5 题)🌱
第 1 题
下面哪一行代码,正确地定义了一个字符串"cat"?
A.char a[3] = "cat";
B.char a[3] = {'c','a','t'};
C.char a[4] = {'c','a','t','\0'};
D.char a[3] = {'c','a','t','\0'};
✅ 正确答案:C
📝 讲解:
字符串必须有
'\0'"cat"需要 4 个位置
第 2 题
下面哪个字符是字符串的结束标志?
A.'0'
B.' '
C.'\n'
D.'\0'
✅ 正确答案:D
📝 讲解:
'\0'是字符串的“小尾巴”
第 3 题
代码如下:
char a[] = "Hi"; cout << sizeof(a);输出结果是?
A. 2
B. 3
C. 4
D. 不确定
✅ 正确答案:B
📝 讲解:
"Hi"实际是H i \0共 3 个字符
第 4 题
下面哪种方式,可以正确输出整个字符数组字符串?
A.cout << a[0];
B.cout << a;
C.cout << &a;
D.cout << *a;
✅ 正确答案:B
📝 讲解:
cout << a会一直输出到'\0'
第 5 题
下面哪个下标是"dog"中'\0'的位置?
char a[] = "dog";A.a[2]
B.a[3]
C.a[4]
D. 没有'\0'
✅ 正确答案:B
📝 讲解:
d(0) o(1) g(2) \0(3)
🧩 二、函数理解关(第 6~10 题)🌿
第 6 题
strlen("cat")的结果是?
A. 2
B. 3
C. 4
D. 5
✅ 正确答案:B
📝 讲解:
strlen不计算'\0'
第 7 题
下面哪个函数,用来比较两个字符数组内容是否相同?
A.==
B.=
C.strcmp
D.strlen
✅ 正确答案:C
第 8 题
代码如下:
char a[10]; strcpy(a, "cat");下面哪句话是正确的?
A.a中没有'\0'
B."cat"复制失败
C.a中存的是"cat"
D. 程序一定会报错
✅ 正确答案:C
第 9 题
下面哪一行代码最安全地把字符数组a清空?
A.a = "";
B.a = 0;
C.memset(a, 0, sizeof(a));
D.strcpy(a, 0);
✅ 正确答案:C
第 10 题
strcmp(a, b)返回0,说明什么?
A.a比b大
B.a比b小
C.a和b内容相同
D. 程序出错
✅ 正确答案:C
🧩 三、陷阱判断关(第 11~15 题)🌳
第 11 题
下面哪段代码是错误的?
A.char a[] = "OK";
B.char a[3] = {'O','K','\0'};
C.char a[2] = "OK";
D.char a[] = {'O','K','\0'};
✅ 正确答案:C
📝 讲解:
"OK"需要 3 个位置
第 12 题
下面代码的输出是?
char a[] = "Hi"; cout << strlen(a);A. 1
B. 2
C. 3
D. 不输出
✅ 正确答案:B
第 13 题
下面哪种输入方式,不能读取带空格的名字?
A.cin >> a;
B.getline(cin, s);
C.cin.getline(a, 20);
D.gets(a);
✅ 正确答案:A
📝 讲解:
cin >>遇到空格就停
第 14 题
代码如下:
char a[5]; strncpy(a, "hello", 5);下面哪句话是正确的?
A.a一定是字符串
B.a一定有'\0'
C.a可能没有'\0'
D. 程序报错
✅ 正确答案:C
第 15 题
下面关于字符数组的说法,正确的是?
A. 字符数组可以没有'\0'
B.strlen会计算'\0'
C. 可以用==比较字符数组内容
D. 字符数组本质是一段连续内存
✅ 正确答案:D
🏆 成绩评价(学生自评)
13~15 分🥇:字符数组小专家
9~12 分🥈:掌握良好,注意坑点
5~8 分🥉:基础已会,需要多练
≤4 分📘:回去再看一遍汉克老师的课程录像 😄