NDK3 C++基础,容器、文件操作
容器
c++中容器,分两种类型
1、序列式容器:元素的排列关系,和元素本身没有任何关系,是我们在添加的时候顺序导致的排序;
2、关联式容器:根据标识,决定 添加 或者 获取 类似于java中的map、set集合;
序列式容器-vector
序列式容器:元素的排列关系,和元素本身没有任何关系,是我们在添加的时候顺序导致的排序;
vector容器的初始化,以下三种方式可以初始化;模板(泛型)
添加元素:push_back;
删除元素:pop_back,删除最新的,也就是最后添加的;
清空元素:clear、erase 两种方式,这两种方式一样;
判断是否清空了:empty;
查看占用的内存空间大小:capacity;
遍历:begin()指向容器中的下标为0的元素迭代器、end();通过指针偏移的方式,进行取出指针的内存地址对应的值;(*beginRsult 是取出指针beginRsult迭代器的内存地址对应的值)
//
// Created by Lenovo on 2021/2/3.
// 容器
//TODO c++中容器,分两种类型
//TODO 1、序列式容器:元素的排列关系,和元素本身没有任何关系,是我们在添加的时候顺序导致的排序;
//TODO 2、关联式容器:根据标识,决定 添加 或者 获取 类似于java中的map、set集合
//
#pragma once
#include <iostream>
#include <string>
#include <vector> //导入系统的容器头文件 // C++ 容器中提供的
using namespace std; //命名空间
int main(){
// cout << 2 << endl;
// TODO 序列式容器
// 初始化容器
vector<int> vec01(1);//声明一个元素的空间 泛型我们这里使用int类型
vector<string> vec02(99,"凯"); //声明99个元素空间,值都是 凯
vector<string> vec03;
//添加元素
vec03.push_back("凯");
vec03.push_back("kai");
vec03.push_back("k");
//遍历vector 容器
vector<string>::iterator beginRsult = vec03.begin();//begin() 指向容器中的下标为0的元素,返回的是迭代器
for (; beginRsult < vec03.end(); beginRsult++){ //指针偏移的方式
//*beginRsult 是取出指针beginRsult的内存地址对应的值
cout << "遍历vector it:" << *beginRsult<< endl;
}
//删除元素
vec03.pop_back();//删除最新的,也就是最后添加的,删除的是 k
//获取元素 两种方式
string value = vec03.at(0);
string value1 = vec03[1];
cout << value << endl;
cout << value1 << endl;
//清空元素 两种方式 等价
vec03.clear(); //第一种
// vec03.erase(vec03.begin(),vec03.end()); //第二种
//是否被清空了
if(vec03.empty()){
cout << "元素已经被清空了" << endl;
}else{
cout << "元素没有清空" << endl;
}
//容器有很严重的问题
//此容器,占用的内存空间,是只增不减的
cout << "vec03此容器占用内存空间是:" << vec03.capacity() << endl;
//TODO 2、关联式容器:根据标识,决定 添加 或者 获取 类似于java中的map、set集合
return 0;
} //main方法执行完毕,所有在栈区申请的内存会全部释放
元素清空,如果是个全局容器,会存在一个问题:内存空间没有释放掉,这个时候我们用下面这种方式来解决;
通过用临时容器,来替换全局容器,全局容器的内存空间就得以释放了;这样的话,一旦方法结束弹栈,临时容器就会被干掉;
//自定义了一个全局的容器
vector<string> allName;
/**
* 全局容器清空,还会占用内存的问题 解决方式
* 替换的方式,来解决 此全局容器清空,还会占用内存的问题
* 定义临时容器目的:就是为了解决 替换全局容器,让清空的全局容器不再占用内存空间
*/
void test01(){
allName.push_back("1");
allName.push_back("22");
allName.push_back("333");
allName.clear();
cout << "allName此容器,清空后占用内存空间是:" << allName.capacity() << endl;
//替换的方式,来解决 此全局容器清空,还会占用内存的问题
vector<string> tempVec;//定义临时容器目的:就是为了解决 替换全局容器,让全局容器不再占用内存空间
//替换全局容器
tempVec.swap(allName); //把全局的allName容器 全部移动到临时容器 全局的allName容器就回收了
} //函数一结束完,弹栈后,tempVec也会被回收了,就保证了,全局和临时的全部回收完毕
优先级队列-priority_queue
优先队列具有队列的所有特性,包括队列的基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的
序列式容器:元素的排列关系,和元素本身没有任何关系,是我们在添加的时候顺序导致的排序;
优先级队列priority_queue 是基于vector实现的;
在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出的行为特征;
基本操作:
push:插入元素到队尾 (并排序);
top:访问队头元素;
size:返回队列内元素个数;
pop:弹出队头元素;
empty:队列是否为空;
front::返回最先入队列的值;
自带排序:
greater:把最小的值,放在最前面;
less : 把最大的值,放在最前面;(默认排序方式)
可以仿照源码中的方式自定义排序,下方代码中有简单的MyTypeLess
//
// Created by Lenovo on 2021/2/3.
// 优先级队列 容器
// 序列式容器:元素的排列关系,和元素本身没有任何关系,是我们在添加的时候顺序导致的排序;
// 优先级队列priority_queue 是基于vector实现的
//
#include <iostream>
#include <string>
#include <queue> //导入系统的容器头文件 // C++ 容器中提供的
#include <vector>
using namespace std;
// TODO 自定义排序方式,自定义自己的类,和排序方式=========start====
class MyType{
public:
int count;
//构造函数
MyType(int count){
this->count = count;
}
};
//模仿源码,定义我们自己的排序规则
struct MyTypeLess
{
bool operator()(const MyType& __x, const MyType& __y) const
{
return __x.count < __y.count; //最大
// return __x.count > __y.count; //最小
}
};
// TODO 自定义排序方式,自定义自己的类,和排序方式=========end====
int main(){
priority_queue<int> priorityQueue;
priorityQueue.push(5);
priorityQueue.push(7);
priorityQueue.push(3);
priorityQueue.push(2);
// priorityQueue.top() 默认把最大的放在最前面
cout << priorityQueue.top() << endl; // 7
cout << priorityQueue.size() << endl; // 4
// TODO 传统方式 排序
// 优先级队列priority_queue 是基于vector实现的
// greater:把最小的值,放在最前面
// less : 把最大的值,放在最前面
priority_queue<int,vector<int>,greater<int>> priorityQueue2;
// priority_queue<int,vector<int>,less<int>> priorityQueue2;
priorityQueue2.push(5);
priorityQueue2.push(7);
priorityQueue2.push(2);
priorityQueue2.push(3);
cout << priorityQueue2.top() << endl; // 2
// TODO 自定义排序方式
priority_queue<MyType,vector<MyType>,MyTypeLess> priorityQueue3;
priorityQueue3.push(MyType(8));
priorityQueue3.push(MyType(5));
priorityQueue3.push(MyType(9));
priorityQueue3.push(MyType(7));
cout << "自定义排序后的top:" << priorityQueue3.top().count << endl;
return 0; //贝尔实验室的时候规定,0表示执行
}
关联式容器-set
关联式容器:根据标识,决定 添加 或者 获取 类似于java中的map、set集合;
重复的元素添加不进去,因为set不允许添加重复的元素;
insert:添加元素;
erase:删除元素;
遍历可通过指针偏移的方式,取出对应的值
//
// Created by Lenovo on 2021/2/3.
// 关联式容器:根据标识,决定 添加 或者 获取 类似于java中的map、set集合
//
#pragma once
#include <iostream>
#include <string>
#include <set>
using namespace std;
int main(){
// 2、关联式容器:根据标识,决定 添加 或者 获取 类似于java中的map、set集合
set<int> set1 = {1,3,2,4,5};
//添加元素
set1.insert(666);
set1.insert(555);
set1.insert(777);
//重复的元素添加不进去,因为set不允许添加重复的元素
set1.insert(1);
set1.insert(2);
set1.insert(3);
//删除元素
// set1.erase(1);
//遍历操作
set<int>::iterator beginRsult = set1.begin();//begin() 指向容器中的下标为0的元素
set<int>::iterator endRsult = set1.end(); //指向容器中的末尾元素的下一位元素
//指针方式 *beginRsult 是取出指针beginRsult的内存地址对应的值
// cout << *beginRsult << endl; //1
// cout << *beginRsult+1 << endl; //2
//遍历
for (; beginRsult!=endRsult; beginRsult++){ //指针偏移的方式
//*beginRsult 是取出指针beginRsult的内存地址对应的值
cout << "遍历set1 it:" << *beginRsult<< endl;
}
// pair<set<int>::iterator, bool> pair1 =set1.insert(222);
return 0;
}
文件操作
C的方式操作
fopen 打开文件,参数1:路径;参数2:模式 r:可以读; w:可以写;
fprintf:写入操作;
fscanf:读取操作;
fclose:关闭流,切记一定要关闭;
fscanf(file2,"%s",buffer);将file2里面的内容读取到了 缓冲buffer中
#pragma once
#include <iostream>
#include <ostream> //输出流
#include <istream> //输入流
#include <fstream>
#include <string>
int main(){
//参数1:路径;
//参数2:模式 r:可以读; w:可以写
//返回值是 FILE * file指针
FILE * file1 = fopen("C:\\Users\\Lenovo\\Desktop\\file.txt","w");
//写入操作
fprintf(file1,"今天是%d号",04);
fclose(file1); //必须关闭资源
FILE * file2 = fopen("C:\\Users\\Lenovo\\Desktop\\日志.txt","r");
//读取操作
//定义接收的缓冲
char buffer[1024]; // 1024 = 1023(字节) + \0 \0代表结尾的符号
//将 file2里面的内容读取到了 缓冲buffer中
fscanf(file2,"%s",buffer);
fclose(file2); //必须关闭资源
cout << "内容:" << buffer << endl; //读取到的只是第一行
// TODO 使用循环读取
// TODO 缺点:一旦遇到空格,就直接放到下一行了
FILE * file3 = fopen("C:\\Users\\Lenovo\\Desktop\\日志.txt","r");
char buffer2[1024]; // 1024 = 1023(字节) + \0 \0代表结尾的符号
while (!feof(file3)){ //没有读取完的情况下
fscanf(file3,"%s",buffer2);
// cout << "循环:" << buffer2 << endl;
}
fclose(file3); //必须关闭资源
// TODO 使用循环读取 最完美的方式 (最常用的,相当于读取一行一行)
//遇到换行,或者\0 也会直接放到下一行了
//解决循环读取的缺点 使用fgets
FILE * file4 = fopen("C:\\Users\\Lenovo\\Desktop\\日志.txt","r");
//为什么1025? 因为1025 = 1024(字节) + \0 \0代表结尾的符号;
//fgets(buffer3,1024,file4); 中读取的是1024个字节,所以需要用1025来接收
char buffer3[1025]; // 1024 = 1023(字节) + \0 \0代表结尾的符号
while (!feof(file4)) { //没有读取完的情况下
fgets(buffer3,1024,file4);
cout << "循环:" << buffer3 << endl;
}
fclose(file4); //必须关闭资源
return 0;
}
C++方式操作
cin >> data; 接收控制台的输入;
ofstream outFile; 代表以写的模式取打开文件(输出对象)
outFile << data << endl;将data的值,丢给了outFile输出对象,写入到文件中;
ifstreamVar >> mydata;将读取的内容,赋值到mydata里面
切记关闭流;
#pragma once
#include <iostream>
#include <ostream> //输出流
#include <istream> //输入流
#include <fstream>
#include <string>
using namespace std;
int main(){
char * fileVar = "C:\\Users\\Lenovo\\Desktop\\fileCpp.txt";
// TODO 写入操作
char data[200];
ofstream outFile; //代表以写的模式取打开文件(输出对象)
outFile.open(fileVar);
//获取用户在控制台输入的信息
cout << "请输入您要保存的信息"<< endl;
//接收用户在控制台输入的信息,赋值到data中,执行此行后,data就收到值了
cin >> data;
//将data的值,丢给了outFile输出对象
outFile << data << endl;
outFile.close(); //关闭输出对象
// TODO 读取操作
char mydata[200];
cout << "读取刚刚保存到文件里面的内容...." << endl;
ifstream ifstreamVar; //代表输入
ifstreamVar.open(fileVar);
//将读取的内容,赋值到mydata里面
ifstreamVar >> mydata;
// 输出
cout << mydata << endl;
ifstreamVar.close();
return 0;
}
辛苦各位童鞋观看到最后,如果博客中有不对的地方望指出,大神勿喷,谢谢~~