- 一、数组
- 二、vector
- 三、字符串简介
- 四、Unicode编码
- 五、字符串的指针表示
- 六、字符串的基本操作
- 七、string简介
- 序列容器概念
- 代表内存里一组连续的同类型存储区
- 可以用来把多个存储区合并成一个整体
- 数组定义:int arr[10] = {1,2,3,4,5,6,7,8};,注意数组里元素个数是不可以改变的
- 数组的访问
#includeusing namespace std; int main(void) { // 数组访问 int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 0, 0 }; // 推荐方式 for (int index = 0; index < 10; ++index) cout << a[index] << " "; cout << endl; // 不推荐方式 for (int index = 0; index <= 9; ++index) cout << a[index] << " "; }
- 数组的查找
#includeusing namespace std; int main(void) { // 数组的查找 int a[] = { 1, 2, 3, 4 }; int len = sizeof(a) / sizeof(a[0]);//得到数组容量 for (int index = 0; index < len; ++index) { if (a[index] == 3) { cout << index << endl; return 0; } } }
- 二维数组
- 将最长的循环放在最内层,最短的循环放在最外层,这样效率更高,减少CPU跨层循环的次数
#include二、vectorusing namespace std; int main(void) { //二维数组的访问: int a[2][4] = { { 1, 2, 3, 4 },{ 5,6,7,8 } }; for (int row = 0; row < 2; ++row) { for (int col = 0; col < 4; ++col) { cout << a[row][col] << " "; } cout << endl; } }
- vector的特点:面向对象、动态数组(动态扩容)
- vector头文件:#include
- vector的使用
- capacity():容量
- size():大小
- begin()、end():起始索引位置、结束索引位置
- push_back:尾部插入元素
- pop_back:尾部移除元素
- insert:任意位置插入元素
- erase:任意位置移除元素
#include三、字符串简介#include using namespace std; int main() { // 创建动态数组vector vector vec = { 1,2,3,4 }; cout << "size is " << vec.size() << endl; cout << "capacity is " << vec.capacity() << endl; // 遍历所有元素 for (int index = 0; index < vec.size(); ++index) { cout << vec[index] << endl; } // 在尾部插入一个元素5 vec.push_back(5); cout << "size is " << vec.size() << endl; cout << "capacity is " << vec.capacity() << endl; // 遍历所有元素 for (int index = 0; index < vec.size(); ++index) { cout << vec[index] << endl; } // 在中间插入一个元素6 vec.insert(--vec.end(), 6); cout << "size is " << vec.size() << endl; cout << "capacity is " << vec.capacity() << endl; // 遍历所有元素 for (int index = 0; index < vec.size(); ++index) { cout << vec[index] << endl; } // 在尾部移除一个元素 vec.pop_back(); cout << "size is " << vec.size() << endl; cout << "capacity is " << vec.capacity() << endl; // 遍历所有元素 for (int index = 0; index < vec.size(); ++index) { cout << vec[index] << endl; } // 在任意位置移除一个元素 vec.erase(vec.end() - 2); cout << "size is " << vec.size() << endl; cout << "capacity is " << vec.capacity() << endl; // 遍历所有元素 for (int index = 0; index < vec.size(); ++index) { cout << vec[index] << endl; } return 0; }
- 字符串变量
- 字符串是以空字符(‘ ’)结束的字符数组
- 空字符(‘ ’)自动添加到字符串内部表示中
- 在声明字符串变量时,应该为这个空结束符预留一个额外元素的空间;
- 如:char strHelloWorld[11] = {"helloworld"};;
- 更简单的方法就是不指定具体长度char strHelloWorld[] = {"helloworld"};
- 字符串常量
- 字符串常量是一对双引号括起来的字符序列
- 字符串中每个字符作为一个数组元素存储
- 例如字符串"helloworld"
- 字符0, ‘ ’, '0’的区别
- char c1 = 0;:0x00
- char c2 = ' ';:0x00
- char c3 = '0';:0x30
- Unicode编码的目的:为了把世界上的文字都映射到一套字符空间中
- Unicode字符集三种编码方式
- UTF-8:1byte表示1个字符,可以兼容ASCII码;特点是存储效率高,变长(不方便内部随机访问),无字节序问题(可以作为外部编码)
- UTF-16:2byte表示1个字符,分为UTF-16BE(big endian)、UTF-16LE(little endian);特点是定长(方便内部随机访问),有字节序问题(不可以作为外部编码)
- UTF-32:4byte表示1个字符,分为UTF-32BE(big endian)、UTF-32LE(little endian);特点是定长(方便内部随机访问),有字节序问题(不可以作为外部编码)
- Windows平台的BOM:Windows的文件可能有BOM(byte order mark),就是处理字节序问题的;如要在其他平台使用,可以去掉BOM;实际这是微软平台的画蛇添足,因为UTF-8并没有字节序问题
- notpad++的编码
- 指针表示法:char* pStrHelloWrold = "helloworld";
- char[]和char*的区别:
- strHelloWorld不可变,strHelloWorld[index]的值可变
- pStrHelloWrold 可变,但是pStrHelloWrold[index]的值是否可变取决于所指区间的存储区域是否可变;当前所指的区域的字符串常量,不可变,所以编译器报错“表达式必须是可修改的左值”
#include六、字符串的基本操作#include using namespace std; int main() { // 定义一个数组 char strHelloWorld[11] = { "helloworld" }; const char* pStrHelloWrold = "helloworld"; for (int index = 0; index < strlen(strHelloWorld); ++index) { strHelloWorld[index] += 1; cout << strHelloWorld[index] << endl; } for (int index = 0; index < strlen(strHelloWorld); ++index) { pStrHelloWrold[index] += 1; // 报错,表达式必须是可修改的左值 cout << pStrHelloWrold[index] << endl; } return 0; }
- 字符串长度strlen(s):返回字符串s的长度,注意不包含’ ’的长度
#includeusing namespace std; int main() { // 定义一个数组 char strHelloWorld[11] = { "helloworld" }; cout << strlen(strHelloWorld) << endl; // 10 cout << sizeof(strHelloWorld) << endl; // 11 return 0; }
- 字符串比较strcmp(s1,s2):两个字符串自左向右逐个字符相比(按ASCII值大小比较),直到出现不同的字符或遇到’ ’为止
- 如果s1和s2是相同的,则返回0
- 如果s1 < s2 则返回值小于0
- 如果s1 > s2 则返回值大于0
#includeusing namespace std; int main() { // 定义一个数组 char strHelloWorld1[] = { "helloworld" }; char strHelloWorld2[] = { "helloworld" }; char strHelloWorld3[] = { "hflloworld" }; char strHelloWorld4[] = { "hdlloworld" }; cout << strcmp(strHelloWorld1, strHelloWorld2) << endl; // 0 cout << strcmp(strHelloWorld1, strHelloWorld3) << endl; // -1 cout << strcmp(strHelloWorld1, strHelloWorld4) << endl; // 1 return 0; }
- 字符串拷贝strcpy(s1,s2):复制字符串s2到字符串s1,s1的空间需要保证能够容纳
- 复制指定长度字符串strncpy(s1,s2,n):将字符串s2中的前n个字符拷贝到s1中,s1的空间需要保证能够容纳
- 字符串拼接strcat(s1,s2):将字符串s2接到s1后面,s1的空间需要保证能够容纳
- 查找字符串strchr(s1,ch):指向字符串s1中字符ch的第一次出现的位置
- 查找字符串strchr(s1,s2):指向字符串s1中字符串s2的第一次出现的位置
注意:请使用strnlen_s,strcpy_s,strncpy_s,strcat_s等API函数,更安全
- 非安全版本示例
#define _CRT_SECURE_NO_WARNINGS #includeusing namespace std; const unsigned int MAX_LEN_NUM = 16; int main() { char strHelloWorld1[] = { "hello" }; char strHelloWorld2[] = { "world1" }; char strHelloWorld3[MAX_LEN_NUM] = { 0 }; strcpy(strHelloWorld3, strHelloWorld1); // hello strncpy(strHelloWorld3, strHelloWorld2, 2);// wollo strcat(strHelloWorld3, strHelloWorld2); //wolloworld1 unsigned int len = strlen(strHelloWorld3); for (unsigned int index = 0; index < len; ++index) { cout << strHelloWorld3[index] << " "; } cout << endl; return 0; }
- 安全版本示例
#include七、string简介using namespace std; const unsigned int MAX_LEN_NUM = 16; const unsigned int STR_LEN_NUM = 7; const unsigned int NUM_TO_COPY = 2; int main() { char strHelloWorld1[] = { "hello" }; char strHelloWorld2[STR_LEN_NUM] = { "world1" }; char strHelloWorld3[MAX_LEN_NUM] = { 0 }; strcpy_s(strHelloWorld3, MAX_LEN_NUM, strHelloWorld1); // hello strncpy_s(strHelloWorld3, MAX_LEN_NUM, strHelloWorld2, NUM_TO_COPY);// wollo strcat_s(strHelloWorld3, MAX_LEN_NUM, strHelloWorld2); //wolloworld1 unsigned int len = strlen(strHelloWorld3); for (unsigned int index = 0; index < len; ++index) { cout << strHelloWorld3[index] << " "; } cout << endl; // 小心缓冲区溢出 strcat_s(strHelloWorld2, STR_LEN_NUM, "Welcome to C++"); return 0; }
string使用起来比原始的C风格方法更安全和方便,对性能要求不是特别高的可以使用
所以如果我们对性能要求比较高,还是建议使用C风格的字符串比较好
- string介绍:C++标准库中提供了string类型专门表示字符串#include
- string的优点:使用string可以更为方便和安全的管理字符串
- 字符串变量的定义
- string s;:定义空字符串
- string s = "helloworld";:定义并初始化
- string s("helloworld");
- string s = string("helloworld");
- 获取字符串长度
- cout << s1.length() << endl;
- cout << s1.size() << endl;
- cout << s1.capacity() << endl;
- 字符串比较:==、!=、>、>=、<、<=
- string s1 = "hello",s2 = "world";
- cout << (s1 == s2) << endl;
- cout << (s1 != s2) << endl;
#include#include using namespace std; int main() { // 字符串定义 string s1;//定义空字符串 string s2 = "helloworld";//定义并初始化 string s3("helloworld"); string s4 = string("helloworld"); // 获取字符串长度 cout << s1.length() << endl;// 0 cout << s1.size() << endl;// 0 cout << s1.capacity() << endl;// 15 // 字符串比较 s1 = "hello", s2 = "world"; cout << (s1 == s2) << endl;// 0 cout << (s1 != s2) << endl;// 1 return 0; }
- string转换为C风格字符串:const char* c_str1 = s1.c_str();
- string随机访问某个字符:s[0] = "h";
- string拷贝:s1 = s2;'
- string连接:直接使用+,+=
#include#include using namespace std; int main() { // 字符串定义 string s1;//定义空字符串 string s2 = "helloworld";//定义并初始化 string s3("helloworld"); // 字符串比较 s1 = "hello", s2 = "world"; cout << (s1 == s2) << endl; cout << (s1 != s2) << endl; // 转换成C风格的字符串 const char* c_str1 = s1.c_str(); cout << "The C-style string c_str1 is: " << c_str1 << endl; // 随机访问 for (unsigned int index = 0; index < s1.length(); ++index) { cout << c_str1[index] << " "; } cout << endl; for (unsigned int index = 0; index < s1.length(); ++index) { cout << s1[index] << " "; } cout << endl; // 字符串拷贝 s1 = "helloworld"; s2 = s1; // 字符串连接 s1 = "helllo", s2 = "world"; s3 = s1 + s2; //s3: helloworld s1 += s2; //s1: helloworld return 0; }



