🔧语法详解 —— 字符数组的声明与初始化
字符数组有 4种初始化方式,每种方式都有其适用场景。
C++4种初始化方式
// 方式1:逐个字符初始化
char s1[5] = {'H', 'e', 'l', 'l', 'o'};
// 方式2:用字符串直接初始化(自动加\0)
char s2[6] = "Hello";
// 方式3:不指定长度(自动计算)
char s3[] = "Hello"; // 长度自动为6(含\0)
// 方式4:全部初始化为0(\0)
char s4[100] = {0}; // 全部元素为\0
对比4种初始化方式对照表
| 方式 | 语法 | 长度 | 末尾\0 | 适用场景 |
| 方式1 | {ch1,ch2,...} | 显式指定 | 无(需手动加) | 精确控制每个字符 |
| 方式2 | "string" | 显式指定 | 自动添加 | 已知字符串内容 |
| 方式3 | "string" | 自动计算 | 自动添加 | 最常用,简洁 |
| 方式4 | {0} | 显式指定 | 全部为\0 | 清空数组/预留空间 |
🧠内存布局可视化 —— 字符数组在内存中长什么样
字符数组在内存中是连续存储的。用字符串初始化时,编译器会自动在末尾添加 '\0'(ASCII码为0)。
char word[6] = "Hello";
0
内存位置: 'H' | 'e' | 'l' | 'l' | 'o' | '\0'
1
下标: 0 | 1 | 2 | 3 | 4 | 5
2
word[0]='H', word[1]='e', word[2]='l', word[3]='l', word[4]='o', word[5]='\0'
3
strlen(word) = 5(不计算\0),sizeof(word) = 6(计算\0)
C++验证内存布局
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char word[6] = "Hello";
for (int i = 0; i < 6; i++) {
cout << "word[" << i << "] = " << (int)word[i] << " ('" << word[i] << "')" << endl;
}
// word[0] = 72 ('H') word[1] = 101 ('e')
// word[2] = 108 ('l') word[3] = 108 ('l')
// word[4] = 111 ('o') word[5] = 0 ('\0')
return 0;
}
⚡易混淆概念对比 —— char数组 vs string类
char 数组(C风格字符串)
- 定义:char s[100] = "Hello";
- 末尾必须有 '\0' 结尾
- 长度固定,不能动态扩容
- 用 strlen() 获取长度
- 用 strcpy/strcat/strcmp 操作
- 数组名是常量指针,不能直接赋值
- sizeof 返回分配的内存大小
string 类(C++风格字符串)
- 定义:string s = "Hello";
- 自动管理 '\0',无需关心
- 长度可变,可以动态扩容
- 用 .length() 或 .size() 获取长度
- 用 + 运算符连接,== 比较
- 可以直接赋值:s = "World";
- 属于 C++ 标准库,更安全
提示:在 CSP-J / NOIP 比赛中,两种都可以用。char 数组更底层、效率更高;string 类更方便、更安全。本讲重点学习 char 数组,后续课程会深入 string 类。
📚案例详解 —— 由浅入深掌握字符数组操作
案例1统计字符串长度(手动 + strlen)
学习字符数组的第一个操作:统计字符串长度。我们可以用 strlen 函数,也可以手动遍历计数。
C++方法一:使用 strlen
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char s[100] = "Hello, World!";
int len = strlen(s);
cout << "字符串: " << s << endl;
cout << "长度: " << len << endl;
return 0;
}
C++方法二:手动遍历计数
#include <iostream>
using namespace std;
int main() {
char s[100] = "Hello, World!";
int len = 0;
while (s[len] != '\0') {
len++;
}
cout << "字符串: " << s << endl;
cout << "长度: " << len << endl;
return 0;
}
运行结果
字符串: Hello, World!
长度: 13
案例2字符串复制(strcpy)
把源字符串的内容复制到目标数组中。注意:目标数组必须有足够的空间!
C++strcpy 字符串复制
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char src[50] = "Hello";
char dst[50];
strcpy(dst, src);
cout << "源字符串: " << src << endl;
cout << "目标字符串: " << dst << endl;
// 手动复制
char dst2[50];
int i;
for (i = 0; src[i] != '\0'; i++) {
dst2[i] = src[i];
}
dst2[i] = '\0';
cout << "手动复制: " << dst2 << endl;
return 0;
}
运行结果
源字符串: Hello
目标字符串: Hello
手动复制: Hello
案例3字符串连接(strcat)
把两个字符串拼接到一起。注意:目标数组必须有足够的空间来容纳拼接后的结果!
C++strcat 字符串连接
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char s1[100] = "Hello";
char s2[50] = " World";
strcat(s1, s2);
cout << "拼接结果: " << s1 << endl;
// 手动连接
char s3[100] = "Hello";
char s4[50] = " World";
int i = 0, j = 0;
while (s3[i] != '\0') i++;
while (s4[j] != '\0') {
s3[i] = s4[j];
i++; j++;
}
s3[i] = '\0';
cout << "手动拼接: " << s3 << endl;
return 0;
}
运行结果
拼接结果: Hello World
手动拼接: Hello World
案例4字符串比较(strcmp)
比较两个字符串是否相同。strcmp 按字典序(ASCII码)逐个字符比较。
C++strcmp 字符串比较
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char a[50] = "Hello";
char b[50] = "Hello";
char c[50] = "World";
if (strcmp(a, b) == 0)
cout << "a 和 b 相同" << endl;
if (strcmp(a, c) < 0)
cout << "a 在字典序中小于 c" << endl;
// 手动比较
int i;
for (i = 0; a[i] != '\0' && b[i] != '\0'; i++) {
if (a[i] != b[i]) break;
}
if (a[i] == '\0' && b[i] == '\0')
cout << "手动比较:a 和 b 相同" << endl;
return 0;
}
运行结果
a 和 b 相同
a 在字典序中小于 c
案例5密码验证程序
综合运用字符数组和字符串函数,实现一个简单的密码验证程序。
C++密码验证
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char correct[20] = "admin123";
char input[20];
int attempts = 3;
cout << "=== 用户登录系统 ===" << endl;
while (attempts > 0) {
cout << "请输入密码 (剩余" << attempts << "次机会): ";
cin >> input;
if (strcmp(input, correct) == 0) {
cout << "登录成功!欢迎回来!" << endl;
return 0;
} else {
attempts--;
cout << "密码错误,请重试!" << endl;
}
}
cout << "账户已锁定,请稍后再试。" << endl;
return 0;
}
运行结果(输入正确密码)
=== 用户登录系统 ===
请输入密码 (剩余3次机会): admin123
登录成功!欢迎回来!
运行结果(连续输错3次)
=== 用户登录系统 ===
请输入密码 (剩余3次机会): 123456
密码错误,请重试!
请输入密码 (剩余2次机会): admin
密码错误,请重试!
请输入密码 (剩余1次机会): wrong
密码错误,请重试!
账户已锁定,请稍后再试。