容器:
序列式容器 vector:
main函数里面:
// TODO 容器 序列式 关联式
// 序列式容器 stl:标准模板库, vector,list,dequeue, queue,stack,priority_queue
// 序列式容器是指:(元素排列顺序与元素本身无关,有添加的顺序决定的)
// 定义一个向量
vector<int> vec01(1); // 声明一个元素空间
vector<string> vec02(999999, "孙悟空"); // 声明999999个 值:“孙悟空”
vector<string> vec03;
// 增加元素
vec03.push_back("杜子腾");
vec03.push_back("戴月荆");
vec03.push_back("史甄湘");
// 删除元素
vec03.pop_back(); // 移除的是 -->“史甄湘”
// 获得元素
cout << /*vec03[0]*/ vec03.at(0) << endl;
cout << vec03[1] << endl;
// 获取 队首 队尾 元素
vec03.front();
vec03.back();
// 清空元素
vec03.clear();
vec03.erase(vec03.begin(), vec03.end());
// 都已经清空元素了,容量还是3,就证明 此容器占用的内存空间是 只增不减的
cout << "获得vector容器容量大小:" << vec03.capacity() << endl;
main函数上面:
#include <iostream>
#include <vector> // C++中定义的模板类
#include <queue> // C++中定义的模板类
#include <stack>
#include <set>
#include <map>
using namespace std;
// TODO 学习 vector 全局vector 内存空间的释放
// 注意:vector容器占用的内存空间是只增不减的
vector<string> allname;
void test01(){
allname.push_back("一");
allname.push_back("二");
allname.push_back("三");
// allname.clear();
allname.erase(allname.begin(), allname.end());
vector<string> tempVecotr;
tempVecotr.swap(allname); // 替换操作 把allname 替换 给了tempVector
cout << "allname.capacity:" << allname.capacity() << endl;
// 当此方法执行结束,tempVector 就会被回收掉
}
int main() {
// 全局vector 如果被清除占用的内存容量大小的
test01();
return 0;
}
queue: queue队列 先进先出
// -----
// queue队列 先进先出
queue<int> queue1;
// 添加到队列
queue1.push(1);
queue1.push(2);
// 弹出队列
queue1.pop();
// queue不建议遍历,不适用遍历
stack栈,后进先出:
// ---
// stack栈 后进先出
stack<int> stack1;
priority_queue:优先级队列:
传统方式:
// 优先级队列 是在vector之上实现的,所以只能写vector<T>
priority_queue<int> priorityQueue;
priorityQueue.push(6);
priorityQueue.push(9);
priorityQueue.push(1);
// 值最大的 在第零个元素 也就是 top
cout << "priority_queue.top():" << priorityQueue.top() << endl;
// 调整 队列 下面这句话的意思就是,优先级队列是基于vector来实现的
priority_queue<int> priorityQueue2(int, vector<int>, greater<int>);
// priority_queue<int> priorityQueue2(int, vector<int>, less<int>);
// less:代表最大的元素在最前面
// greater:代表最小的元素在最前面
自定义方式:
main函数上面:
// TODO 为了学习优先级队列 priority_queue
class MyType
{
public:
int count;
MyType(int count) {
this->count = count;
}
};
// 自定义排序规则,才能给 MyType这个类,进行排序
struct MyTypeLess { // functor for operator<
// C++ 在结构体可以写函数
constexpr bool operator()(const MyType& _Left, const MyType& _Right) const {
return _Left.count < _Right.count;
}
};
main函数:
// 由于此优先级队列,不知道如何给这个MyType类排序,而出现的错误
priority_queue<MyType, vector<MyType>, MyTypeLess> pqMyType;
pqMyType.push(MyType(1));
pqMyType.push(MyType(9999992));
pqMyType.push(MyType(3));
cout << "pqMyType.top():" << pqMyType.top().count << endl;
关联式容器
// ---- 关联式容器
// 通过一个关键字 来保存 和 访问 元素的 例如:Java中的 map set 都是关联式容器
set<int> set1 = {1,2,3,4,5};
set1.insert(999);
set1.insert(888);
set1.insert(777);
set1.insert(1); // 重复的元素添加不进去,因为set不允许 添加重复的元素
set1.insert(2); // 重复的元素添加不进去,因为set不允许 添加重复的元素
set1.insert(3); // 重复的元素添加不进去,因为set不允许 添加重复的元素
cout << "set1.size:" << set1.size() << endl;
// 删除元素
set1.erase(1);
pair<set<int>::iterator, bool> pair1 = set1.insert(1900000);
// 使用迭代器
set<int>::iterator beginResult = set1.begin(); // 指向容器中 第零个元素
set<int>::iterator endResult = set1.end(); // 指向容器中,最后一个 的下一个元素
cout << "beginResult:" << *beginResult << endl;
// 遍历set
for (; beginResult != set1.end() ; beginResult++) {
cout << "遍历set it:" << *beginResult << endl;
}
// 遍历vector
vector<string> vectorStr;
vectorStr.push_back("11");
vectorStr.push_back("22");
vectorStr.push_back("33");
vectorStr.push_back("44");
vectorStr.push_back("55");
vectorStr.push_back("66");
vector<string> :: iterator it = vectorStr.begin();
for (; it < vectorStr.end() ; it ++) {
cout << "遍历vector:" << *it << endl;
}
// -----
// map
map<int, string> map1;
map<int, string> map2 = { {1, "a"}, {2, "b"} }; // 不能有重复的元素和set一样
map2[2] = "bbb";
类型转换:
main函数里面:
// TODO 类型转换
// C++的新式转换 转换操作符
// const_cast:主要是 修改类型的const
const char *c1 = "#x001241";
char* c2 = const_cast<char*>(c1);
char * c3 = "#x581545";
const char * c4 = const_cast<const char*>(c3);
main函数上面:
// TODO 为了学习转换
class Person {
public:
virtual void show() {
cout << "父类 Person show" << endl;
}
};
class Student : public Person {
public:
void show() {
cout << "子类 Student show" << endl;
}
};
main函数里面:
// C++的静态转换 转换操作符
// static_cast:
// 1.基础类型的互转,例如:int转float,int转unsigned init 等操作
// 2.指针与void之间的互转,例如:float* 转 void* , 函数指针 转 void* 等操作
// ...
Person * person = new Person;
Student * student = static_cast<Student*>(person);
student->show();
delete person;
// 如果不想使用 以上类型的 类型转换操作符,也可以使用 “强制类型转换”
main函数里面:
// C++ Dynamic_cast 转换
Person * person2 = /*new Person*/ /*这样就可以转换成功了*/new Student;
Student * student2 = dynamic_cast<Student*>(person2); // 父类必须要有一个虚方法
cout << "取出内存地址看看:" <<&student2 << endl;
// 如果转换失败,student2 就是 空,所有必须要判断才行
if (student2) {
cout << "转换Success" << endl;
(*student2).show();
// student2->show();
} else {
cout << "转换失败" << endl;
}
delete person2;
// 其他类型的转换
char * string1 = "排云掌";
int i = atoi(string1);
cout << "i:" << i << endl; // 0 只是说明可以 char* 转 int 把排云掌转int没有意义
char * value1 = "666";
int i2 = atoi(value1);
char * value2 = "666.6";
float i3 = atof(value2);
float i4 = atof("999.9f");
cout << "i2:" << i2 << " i3:" << i3 << " i4:" << i4 << endl; // 这样的需求才有意义哦
// ----
char cArray[10];
// 参数一:是一个int类型, 参数二:是要传递char*指针(用数组当然是可以的) ,参数三:代表10进制
itoa(7447565, cArray, 10);
cout << "cArray:" << cArray << endl;
// -----
char cArray2[10];
sprintf(cArray2, "%d", 4777665);
cout << "cArray2:" << cArray2 << endl;
异常:
main函数上面:
// TODO 为了学习异常
void exceptMethod01() {
throw "我报错了,9527...";
}
void exceptMethod02() {
throw exception("我报废了,9687.。。");
}
// 自定义异常
class CustomExceptionClass : public exception
{
public:
virtual char const* what() const
{
return "CustomExceptionClass 自定义异常";
}
};
void exceptMethod03() {
CustomExceptionClass c;
throw c;
}
// 随便自定义一个类,作为异常类,都是可以的
class Dog
{
public:
char * name;
void showName() {
cout << "捕获到exceptMethod04函数发生了异常: shouName:" << this->name << endl;
}
};
void exceptMethod04() {
Dog d;
d.name = "阿黄";
throw d;
}
main函数里面:
// TODO 异常
try {
exceptMethod01();
} catch (const char* exceptionMessage) {
cout << "捕获到exceptMethod01函数发生了异常,异常详情:" << exceptionMessage << endl;
}
try {
exceptMethod02();
} catch (exception &e) {
cout << "捕获到exceptMethod02函数发生了异常,异常的信息:" << e.what() << endl;
}
try {
exceptMethod03();
} catch (CustomExceptionClass &exceptionClass) {
cout << "捕获到exceptMethod03函数发生了异常,信息是:" << exceptionClass.what() << endl;
}
try {
exceptMethod04();
}catch (Dog &d) {
d.showName();
}
文件流:
// TODO 文件流
// 文本的形式 写入
FILE* file1 = fopen("D:\\NDK\\NDK\\CoursewareCreate\\ndk_05\\file.txt", "w"); // w:代表可写
// 在Windows上 文件格式是 GB2312的,在Mac上有乱码的
fprintf(file1, "今天是%d号。", 11);
fclose(file1); // 一定要关闭,和Java中的一样
// 文本的形式 读取文件
FILE* file2 = fopen("D:\\NDK\\NDK\\CoursewareCreate\\ndk_05\\file.txt", "r"); // r:代表可读
char buffer[1024]; // 最大可以读取1023个字节,+ /0
fscanf(file2, "%s", buffer); // 如果遇到,空格,就直接返回了 结束读取
cout << "文件的内容是:" << buffer << endl;
fclose(file2);
// // 如果遇到,空格,就直接返回了 结束读取, 所以需要 循环读取
FILE* file3 = fopen("D:\\NDK\\NDK\\CoursewareCreate\\ndk_05\\file2.txt", "r"); // r:代表可读
char buffer2[1024]; // 最大可以读取1023个字节,+ /0
while(!feof(file3)) {
fscanf(file3, "%s", buffer2);
cout << "文件的内容是:" << buffer2 << endl;
}
fclose(file3);
// 遇到 换行,/0 都会结束读取, 读取1024个字节
FILE* file4 = fopen("D:\\NDK\\NDK\\CoursewareCreate\\ndk_05\\file2.txt", "r"); // r:代表可读
char buffer3[1025]; // + /0
fgets(buffer3, 1024, file4); // 读取1024个字节,这种很明确
cout << "file4:" << buffer3 << endl;
fclose(file4);
// TODO 文件流C++
char * file = "D:\\NDK\\NDK\\CoursewareCreate\\ndk_05\\file3.txt";
// 写入
char data[200];
ofstream outFile; // 以写的模式去打开文件
outFile.open(file);
// 捕获用户在控制台输入信息
cout << "请您输入您要保存的信息:" << endl;
cin >> data; // 接收终端的输入信息,赋值给 data
// 把数据data 写入到文件中去
outFile << data << endl;
// 关闭上面打开的文件
outFile.close();
// -- 读取
char myData[200];
cout << "开始 自动的去读取 刚刚保存到文件里面的内容...." << endl;
ifstream ifstreamVar;
ifstreamVar.open(file);
ifstreamVar >> myData;
cout << myData << endl;
// 关闭
ifstreamVar.close();