1.标准输入输出流
cin与cout的使用,就不多说了,说一个有关保留小数位数的操作,使用ostream对象的precision()方法,表达的意思是数字总共有几位,注意,此时是包括整数部分的;set()方法表示换成保留小数点后位数。例如
#include<bits/stdc++.h>
using namespace std;int main()
{// 请在此输入您的代码cout.precision(2);cout.setf(ios::fixed);cout<<3.1415926<<endl;cout.unsetf(ios::fixed);cout<<3.1415926<<endl;return 0;
}
先是整体位数,在变成小数点位数,再变回来,注意代码实现。
#include<bits/stdc++.h>
using namespace std;int main()
{// 请在此输入您的代码cout<<setprecision(4)<<fixed;cout<<3.1415926<<endl;cout<<defaultfloat;cout<<3.1415926<<endl;cout<<setprecision(6);cout<<3.1415926<<endl;return 0;
}
这是另一种写法,不过需要头文件,代码中我是使用了万能头文件;
下面是有关数据读入的方法:
string s;getline(cin,s);cout<<s<<endl;cout<<s.length()<<endl;
字符串流
类型转换,将"123456"转换成123456
#include<bits/stdc++.h>
using namespace std;int main()
{string s("123456");stringstream ss;ss<<s;int i;ss>>i;cout<<i<<endl;return 0;
}
2.容器
2.1 栈
2.2 队列
2.3 链表
2.4双端队列
2.5 vector向量,数组
2.6 map
表,存放一个键key到值value的映射
2.7优先队列
3 函数(算法)
3.1 排序
sort()是优化后的快排
3.2二分
3.3 二分答案
3.4 填充
全排列
4 迭代器 iterator
有趣的操作,就是对容易进行遍历,不过是利用指针操作的;使用begin返回容器第一个元素的位置,然后不断++;直到end;end是最后一个元素的下一个位置;
#include<iostream>
#include<vector>
using namespace std;
int main(){vector<int> intVect;for(int i=0;i<10;i++){intVect.push_back(i);}cout<<"vec: "<<endl;// for(int i=0;i<10;i++){// cout<<&intVect[i]<<" ";// }// cout<<endl;// cout<<&intVect.end()<<endl;vector<int>:: iterator it = intVect.begin(); //定义一个迭代器/*begin,end是迭代器的专属函数;begin表示获取指向第一个元素位置的迭代器。end表示指向最后一个元素之后的下一个位置的迭代器!!!注意,不是最后一个元素;因此我尝试相反迭代,也就是从end往start;第一个打印的元素都是0,就是数组范围外的元素,默认为0;而返回不到第一个元素,因为到第一个元素就停止了。因此正向的迭代终止位置是,最后一个位置的下一个内存,而不是最后一个内存*/while(it!=intVect.end()){ //直到遍历到vector最后一位之后cout<<*it<<endl; //打印迭代器内容it++; //迭代器不断向后更新}// for(std::iterator it2 = intVect.begin(); it2!=intVect.end();it2++){// }return 0;
}
简单的迭代器就是这样,实际就是指针的操作,因此可以利用迭代器进行容器赋值,容器读取。可以向前遍历,向后遍历,同样可以随机访问:*(it+2)。跟指针一样。
5右值引用与移动语义
左值表征一个对象,一定占据内存
即使编译器做优化使其实际不占内存
lvalue-》可以被取地址;除非使用const修饰的-》有名字的表达式都是左值,除了枚举
因此将左值放在等式右边,将会报错
rvalue并不表征一个对象,非左值的表达式是右值。-》右值要在等号右边,给左值做处理;
纯右值-》如果一个函数返回一个结构体,需要访问该返回值的某个内部成员变量。此时,该结构体是右值,但,该返回结构体必须占内存,却又满足左值特征,临时占一片地址。上面说的传统右值是临时的,并不会占内存,因此纯右值是一种特殊的右值
根据这种特性,将右值又分为了纯右值prvalue和将亡值xvalue;
右值引用只能被右值表达式初始化。
复制就是复制一份新的数据,但是移动就是将原对象指向资源的指针,赋给新的对象成员,也就是将所有权进行转移,也就是数据的指针指向新对象。
6 智能指针
C++指针得设计存在一系列的使用不方便,比如,对于一个指针,要在合适得地方进行delete;指针的指向变换,容易造成对于同一片区域得多次delete;当指针作为函数参数时,很难确定他是作为数组得首地址,还是单变量得指针,那释放地址得操作更不能确定了,因此C++提供一种智能指针,自动释放内存,且只有一个指针指向该内存,也就是唯一性
#include<iostream>
#include<memory>class Cat{
public:Cat(){ this->name = "default"; std::cout<<" con! "<<std::endl;};Cat(std::string name){this->name=name; std::cout<<" con! "<<std::endl;};void show(){ std::cout<<this->name<<std::endl;};void set_name(std::string name){this->name = name;};~Cat(){std::cout<<" decon!"<<std::endl;};
private:std::string name;
};int main(){Cat* demo1 = new Cat("oo");//std::unique_ptr<Cat> un_demo1{demo1}; //第一种智能指针创建方式,根据以后裸指针创建//std::unique_ptr<Cat> un_demo1{new Cat("lk")}; //第二种智能指针创建方式,new一个对象赋值给智能指针std::unique_ptr<Cat> un_demo1 = std::make_unique<Cat>(); //第三种智能指针创建方式,利用mask_uniquedemo1 = NULL;un_demo1->show();un_demo1->set_name("new");un_demo1->show();//delete demo1;return 0;
}
首先确定,unique_ptr只能指向一个地址,因此,只能移动所有权,不能复制,将一个指针赋值给另一个智能指针,需要使用move,将地址的所有权转移,move本身是上一节移动语义说到的操作,将左值变成右值.