3、C++基础容器

一、数组

  • 序列容器概念
    • 代表内存里一组连续的同类型存储区
    • 可以用来把多个存储区合并成一个整体
  • 数组定义int arr[10] = {1,2,3,4,5,6,7,8};,注意数组里元素个数是不可以改变的
  • 数组的访问
#include <iostream>

using 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] << " ";
}
  • 数组的查找
#include <iostream>

using 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 <iostream>

using 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的特点:面向对象、动态数组(动态扩容)
  • vector头文件#include <iostream>
  • vector的使用
    • capacity():容量
    • size():大小
    • begin()、end():起始索引位置、结束索引位置
    • push_back:尾部插入元素
    • pop_back:尾部移除元素
    • insert:任意位置插入元素
    • erase:任意位置移除元素
#include <iostream>
#include <vector>
using namespace std;

int main()
{
	// 创建动态数组vector
	vector<int> 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;
}

三、字符串简介

  • 字符串变量
    • 字符串是以空字符(‘\0’)结束的字符数组
    • 空字符(‘\0’)自动添加到字符串内部表示中
    • 在声明字符串变量时,应该为这个空结束符预留一个额外元素的空间;
      • 如:char strHelloWorld[11] = {"helloworld"};
      • 更简单的方法就是不指定具体长度char strHelloWorld[] = {"helloworld"};
  • 字符串常量
    • 字符串常量是一对双引号括起来的字符序列
    • 字符串中每个字符作为一个数组元素存储
    • 例如字符串"helloworld"
  • 字符0, ‘\0’, '0’的区别
    • char c1 = 0;:0x00
    • char c2 = '\0';:0x00
    • char c3 = '0';:0x30
      在这里插入图片描述

四、Unicode编码

  • 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 <iostream>
#include <vector>
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的长度,注意不包含’\0’的长度
#include <iostream>
using namespace std;

int main()
{
	// 定义一个数组
	char strHelloWorld[11] = { "helloworld" };
	cout << strlen(strHelloWorld) << endl; // 10
	cout << sizeof(strHelloWorld) << endl; // 11
	return 0;
}
  • 字符串比较strcmp(s1,s2):两个字符串自左向右逐个字符相比(按ASCII值大小比较),直到出现不同的字符或遇到’\0’为止
    • 如果s1和s2是相同的,则返回0
    • 如果s1 < s2 则返回值小于0
    • 如果s1 > s2 则返回值大于0
#include <iostream>
using 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

#include <iostream>
using  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 <iostream>
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简介

string使用起来比原始的C风格方法更安全和方便,对性能要求不是特别高的可以使用
所以如果我们对性能要求比较高,还是建议使用C风格的字符串比较好

  • string介绍:C++标准库中提供了string类型专门表示字符串#include <string>
  • 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 <iostream>
#include<string>

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 <iostream>
#include<string>

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休止符

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值