15.数组-字符数组
15.1 知识点
字符数组的声明和初始化
字符数组就是类型为字符 char
的一维数组。
常用方式:
方式一:聚合初始化
char charArr[5] = { 'H', 'E', 'L', 'L', 'O' };
char charArr2[] = { 'H', 'E', 'L', 'L', 'O' };
方式二:单独初始化
char charArr3[5];
charArr3[0] = 'H';
charArr3[1] = 'E';
这几种声明初始化的方式,如果直接将字符数组拿来打印,会出现问题:
cout << charArr << endl; // 乱码 烫烫烫烫
cout << charArr2 << endl; // 乱码 烫烫烫烫
cout << charArr3 << endl; // 乱码 烫烫烫烫
使用字符串初始化字符数组
可以直接使用字符串对字符数组进行赋值:
char charArr4[] = "Hello World"; // string
cout << charArr4 << endl; // Hello World 正常打印
原本看起来只有12个字符的字符串,但是长度却有13个:
int length = sizeof(charArr4) / sizeof(char);
cout << length << endl; // 13
通过观察长度,我们发现了一个潜在规则:对字符数组用字符串去赋值时,会默认在尾部加上一个 \0
的转义字符,表示字符串的结束。前面几种初始化方式不会默认添加 \0
,所以会出现乱码。
手动加 \0
:
char charArr44[] = "Hello\0 World"; // string
cout << charArr44 << endl; // Hello
利用结束符号决定字符数组表示的字符串何时结束
尝试自定义\0位置决定字符串何时结束
如果不对字符数组后面的内容进行初始化,并且其中没有 \0
,在打印时就不知道何时结束,程序会不停地往后读取。由于没有明确的终止符,程序会根据内存中是否存在 \0
停止打印,可能打印出多余字符,甚至是乱码。
这意味着可能出现访问到字符数组范围之外的内存区域,产生未定义的行为。
char charArr5[5];
charArr5[0] = 'A';
charArr5[1] = 'B';
// cout << charArr5[2] << endl; // 空
// cout << charArr5 << endl; // AB烫烫烫烫烫烫烫烫烫烫烫烫烫愼@
charArr5[2] = 'X';
charArr5[3] = 'C';
charArr5[4] = '\0';
cout << charArr5[2] << endl; // X
cout << charArr5 << endl; // ABXC
关于“烫”字符
在内存中,汉字字符使用多字节编码(如 UTF-8 或 GBK)。当程序读取到这些内存内容时,会尝试解释它们。由于编码规则,有可能形成合法的汉字编码,导致控制台上显示出汉字或其他非预期字符。
15.2 知识点代码
Lesson15_数组_字符数组.cpp
#include <iostream>
using namespace std;
int main()
{
std::cout << "字符数组\n";
#pragma region 知识点一 字符数组的声明和初始化
//字符数组就是类型为字符char的一维数组
//常用方式:
//方式一:聚合初始化
char charArr[5] = { 'H', 'E', 'L', 'L', 'O' };
char charArr2[] = { 'H', 'E', 'L', 'L', 'O' };
//方式二:单独初始化
char charArr3[5];
charArr3[0] = 'H';
charArr3[1] = 'E';
//这几种声明初始化的方式,如果直接将字符数组拿来打印 会出现问题
//cout << charArr << endl;//乱码 烫烫烫烫
//cout << charArr2 << endl;//乱码 烫烫烫烫
//cout << charArr3 << endl;//乱码 烫烫烫烫
#pragma endregion
#pragma region 知识点二 使用字符串初始化字符数组
//可以直接使用字符串对字符数组进行赋值
char charArr4[] = "Hello World"; //string
cout << charArr4 << endl;//Hello World 正常打印
//原本看起来只有12个字符的字符串 但是长度却有13个
int length = sizeof(charArr4) / sizeof(char);
cout << length << endl;//13
//通过观察长度,我们发现了一个潜在规则
//对字符数组用字符串去赋值时,会默认在尾部加上一个\0的转移字符
//代表字符串的结束
//前面几种初始化方式不会默认添加\0 所以会乱码
//手动加\0 检测到\0后不会打印后面的字符了
char charArr44[] = "Hello\0 World"; //string
cout << charArr44 << endl;//Hello
#pragma endregion
#pragma region 知识点三 利用结束符号决定字符数组表示的字符串何时结束
//如果不对字符数组后面的内容进行初始化 并且其中没有\0
//在打印时就不知道何时结束,就会不停的往后读取
//因为没有明确的终止符,程序会根据内存中是否存在 '\0' 停止打印
//可能打印出多余字符,甚至是乱码
//也就是说可能出现访问到字符数组范围之外的内存区域,产生未定义的行为
char charArr5[5];
charArr5[0] = 'A';
charArr5[1] = 'B';
//cout << charArr5[2] << endl;//空
//cout << charArr5 << endl;//AB烫烫烫烫烫烫烫烫烫烫烫烫烫愼@
charArr5[2] = 'X';
charArr5[3] = 'C';
charArr5[4] = '\0';
cout << charArr5[2] << endl;//X
cout << charArr5 << endl;//ABXC
//关于“烫”字符
//在内存中,汉字字符使用多字节编码(比如 UTF-8 或 GBK)
//当程序读取到这些内存内容时,会尝试解释它们。
//由于编码规则,有可能形成合法的汉字编码,导致控制台上显示出汉字或其他非预期字符
#pragma endregion
}
15.3 练习题
字符数组中,为什么要注意加入\0转移字符?
因为\0转移字符代表结束,如果没有它,当我们使用字符数组用于打印时,会不知道何时停止,导致越界打印。
利用所学知识点,你认为打印出的“烫”可能占几个字节?
在不同编码格式中,”烫”可能所占字节数各不相同,编码值也不同。
- 在UTF-8中,”烫”占3个字节
- 在UTF-16中,”烫”占2个字节
- 在GBK中,”烫”占2个字节
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com