目录
字符数组的"身份证"
字符数组本质上就是个char
类型的旅馆!每个房间(元素)只能住一个字符,而且必须给结束符\0
预留床位(重要的事情说三遍:结束符!结束符!结束符!)。比如要存"Hello",需要至少6个元素的数组:
char str[6] = {'H','e','l','l','o','\0'}; // 标准写法
char str[] = "Hello"; // 编译器自动加\0(偷懒写法)
5种初始化姿势大比拼
- 静态初始化(适合已知内容)
char password[9] = {'p','@','s','s','w','0','r','d','\0'};
- 动态赋值(运行时才知道内容)
char username[20];
for(int i=0; i<5; i++){
username[i] = 'A' + i; // 生成ABCDE
}
username[5] = '\0'; // 千万别忘!!!
- 字符串常量赋值(最常用)
char error_msg[] = "File not found!"; // 自动计算长度
- 指针混搭法(高阶玩法)
char *p = "Hello World"; // 其实指向常量区
char arr[] = "Hello World"; // 这才是真数组
- 部分初始化(危险操作)
char buffer[10] = {'a','b'}; // 剩余元素自动补0(即\0)
输入输出的那些坑
scanf的三大罪状
char name[5];
scanf("%s", name); // 输入"Jackson"直接崩!(缓冲区溢出)
推荐使用fgets
保平安:
fgets(name, sizeof(name), stdin); // 自动限制长度
puts与printf的爱恨情仇
char str[] = "Hello\0World";
puts(str); // 输出Hello(遇到\0就停)
printf("%s", str); // 同上
printf("%c", str[6]); // 输出'r'(证明数据还在)
新手必踩的3个深坑
坑1:忘写结束符
char arr[5] = {'H','e','l','l','o'}; // 没有\0!
printf("%s", arr); // 输出hello+乱码(直到遇到内存中的0)
坑2:数组越界
char str[3] = "C++"; // 正确写法是str[4]
// 实际内存:'C' '+' '+' '\0'(越界写入!)
坑3:单引号双引号混淆
char ch = "A"; // 错误!应该用单引号'A'
char str = 'ABCD'; // 错上加错!
实战:字符串反转
#include <stdio.h>
#include <string.h>
void reverse_string(char str[]) {
int len = strlen(str);
for(int i=0; i<len/2; i++){
char temp = str[i];
str[i] = str[len-1-i];
str[len-1-i] = temp;
}
}
int main() {
char text[] = "emocleW ot efil";
reverse_string(text);
printf("%s", text); // 输出"life to Welcome"
return 0;
}
总结清单
- ✅ 数组长度 >= 字符串长度+1
- ✅ 输入用fgets代替gets/scanf
- ✅ 操作前检查数组边界
- ✅ 处理完手动添加\0
- ✅ 慎用strcpy/strcat等危险函数
(终极提示)字符数组就像女朋友——你得时刻注意她的边界,及时表达终止意向(\0),还要小心她突如其来的脾气(缓冲区溢出)!