CPP学习
CPP算法之路,不涉及面向对象
C++向下兼容C,没有特别强调的地方就用C来写好啦~
(我爱C,我爱C++)
正文
点击查看代码
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
cout << "hello, chunlei" << n + 1 << endl;
return 0;
}
头文件
补充一点,竞赛的时候可以使用#include <bits/stdc++.h>,包含几乎所有常见 C++ 标准库头文件的集合,因此你可以通过包含它来方便地使用各种库。
C++的头⽂件⼀般是没有像C语⾔的 .h 这样的扩展后缀的,⼀般情况下C语⾔⾥⾯的头⽂件去掉 .h 然后在前⾯加个 c 就可以继续在C++⽂件中使⽤C语⾔头⽂件中的函数啦~⽐如:
#include <cmath> // 相当于C语⾔⾥⾯的#include <math.h>
#include <cstdio> // 相当于C语⾔⾥⾯的#include <stdio.h>
#include <cctype> // 相当于C语⾔⾥⾯的#include <ctype.h>
#include <cstring> // 相当于C语⾔⾥⾯的#include <string.h>
文件有的使用<>,有的是用"",有什么区别内?
<>
先去系统目录中找头文件,如果没有就到当前目录下找。像标准的头文件stdio.h,stdlib.h等就是这个方法
""
先在当前目录下找,如果没有就到系统目录下找。主要用于include自定义的头文件
文件后缀有的是.h,有的是.cpp,有什么区别内?
.h
中存放类的声明和函数原型
.cpp
存放函数体
命名空间using namespace std到底是什么意思
这句话声明了一个命名空间std
命名空间在多人合作写项目时很有用。因为你定义了变量 a,别人也定义了变量 a,这样就重复定义了。如果你在自己的命名空间中定义了 a,别人在别人的命名空间中定义了 a,这样就不重复了,比如:
using namespace xx;
using namespace yy;
xx::a 和 yy::a 虽然都叫 a,但是不是同一个变量。
std 是系统标准的命名空间,为了和用户定义的名字不重复,所以它声明在 std 这个命名空间中。这个空间包括了系统所有的支持,比如cin,cout等等。
如果不加using namespace std; ,就需要在每一行代码前加上std::
std::cin >> n;
std::cout << "hello, chunlei" << n + 1 << endl;
丑丑的。所以还是在一开始加上比较好,省时省力又好看(๑•ᴗ•๑)♡
cin和cout
和printf、scanf一样,cin和cout在头文件iostream中。
关于iostream
看名字就知道,i是input,o是output,所以这个头文件里包含的方法就是管理一些输入输出流的
cin>>n,表示输入
cout<<n,表示输出
非常的清晰方便,不需要写取地址符,不需要写类型,nice~(๑•ᴗ•๑)♡
BUT,虽然cin和cout用起来方便,但是效率不如scanf和printf。所以对算法复杂度不高的题目可以用,对于算法复杂度要求高的题目使用scanf和printf可以提高效率
关于endl和"\n"
可以使用"\n"代替endl,微小区别是endl会比"\n"换行后多一个刷新输出缓冲区的操作。无伤大雅
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, world!" << "\n";
return 0;
}
如果前面是字符串的话会方便一些
cout << "hello, chunlei~\n";
如果前面是变量的话endl会方便一些
cout << n << endl;
哈哈都可以啦O(∩_∩)O
变量的声明
C语言的变量声明一般都在函数开头,但是C++在首次使用变量之前声明即可。当然也可以都放在函数开头
bool变量
有两个值,true和false。
C++把所有非零值解释为true,零值解释为false。所以直接赋值一个数字给bool变量也是可以的。他会自动根据int值是否为零来决定给bool变量赋值为true还是false
bool flag = true;
bool flag2 = -2; // flag2为true
bool flag3 = 0; // flag3为false
使用const定义变量
和C相同
字符串
C++的字符串有两种形式:C风格字符串和string类
C风格字符串:以null结尾的字符数组
string类好用到停不下来:有了string类,定义、拼接、输出、处理都十分方便
string s = "hello world"; // 赋值
string s2 = s;//赋值
string s3 = s + s2; // 字符串拼接直接⽤+号就可以
string s4;
cin >> s4; // 读⼊字符串
cout << s; // 输出字符串
string中还有个很常用的函数叫做substr,作用是截取某个字符串中的子串
string s2 = s.substr(4); // 表示从下标4开始⼀直到结束
string s3 = s.substr(5, 3); // 表示从下标5开始,3个字符
注意!
1.string只能用cin和cout处理,无法使用scanf和printf
2.用cin读入字符串的时候,是以空格为分隔符的,如果想要读入一整行的字符串,就需要用到getline
3.字符串的长度可以用.length
获取,而且有几个字符长度就是多少,不存在字符数组里面的什么末尾结束符之类的(。・ω・。)ノ♡
string s; // 定义⼀个空字符串s
getline(cin, s); // 读取⼀⾏的字符串,包括空格
cout << s.length(); // 输出字符串s的⻓度,包括空格哦
比如输入:chun lei,共有8个字符
指针
(美好的世界怎么可以没有指针₍₍٩( ᐛ )۶₎₎♪)
所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
指针的算术运算
-
加法运算:可以对指针进行加法运算。当一个指针p加上一个整数n时,结果是指针p向前移动n个元素的大小。例如,如果p是一个int类型的指针,每个int占4个字节,那么p + 1将指向p所指向的下一个int元素。
-
减法运算:可以对指针进行减法运算。当一个指针p减去一个整数n时,结果是指针p向后移动n个元素的大小。例如,如果p是一个int类型的指针,每个int占4个字节,那么p - 1将指向p所指向的前一个int元素。
-
指针与指针之间的减法运算:可以计算两个指针之间的距离。当从一个指针p减去另一个指针q时,结果是两个指针之间的元素个数。例如,如果p和q是两个int类型的指针,每个int占4个字节,那么p - q将得到两个指针之间的元素个数。
-
指针与整数之间的比较运算:可以将指针与整数进行比较运算。可以使用关系运算符(如<、>、<=、>=)对指针和整数进行比较。这种比较通常用于判断指针是否指向某个有效的内存位置。
结构体
(当时C这一块没学好,好好记笔记ing(◞‸◟ ))
定义结构
点击查看代码
#include <iostream>
using namespace std;
void printbook(struct Books book);
struct Books
{
string name;
string author;
string subject;
int id;
}book1,book2;
int main()
{
//book1
book1.name="heihei";
book1.author="lichunlei";
book1.subject="sha";
book1.id=1;
//book2
book2.name="haha";
book2.author="lichunlei";
book2.subject="ben";
book2.id=2;
printbook(book1);
printbook(book2);
return 0;
}
void printbook(struct Books book)
{
cout << "title : " << book.name <<endl;
cout << "author : " << book.author <<endl;
cout << "subject : " << book.subject <<endl;
cout << "id : " << book.id <<endl;
}
访问
使用.
运算符
作为函数参数
把他当做一个普通的变量就好啦
注意!
C++结构体里面可以定义构造函数
使用结构体的时候,C需要些关键字struct,C++不需要
struct stu {
int grade;
float score;
};
struct stu arr1[10]; // C语⾔⾥⾯需要写成struct stu
stu arr2[10];// C++⾥⾯不⽤写struct,直接写stu就好啦
指向结构的指针
点击查看代码
#include <iostream>
using namespace std;
//声明一个结构体Books
struct Book{
string name;
string author;
string subject;
int id;
//构造函数
Book(string name, string author, string subject, int id):name(name), author(author), subject(subject), id(id){
}
};
//打印
void printBookInfo(const Book& book)
{
cout << "name: " << book.name << endl;
cout << "author: " << book.author << endl;
cout << "subject: " << book.subject << endl;
cout << "ID: " << book.id << endl;
}
int main()
{
Book book1("C++ Primer", "Bjarne Stroustrup", "Programming", 101);
Book book2("C++ Primer Plus", "Bjarne Stroustrup", "Programming", 102);
printBookInfo(book1);
printBookInfo(book2);
return 0;
}
->
箭头运算符
引用
C++中的引用符号&和C语言中的取地址符&要区分开,他们没有什么关系~
C++里面的引用是指在变量之前加一个&符,对引用变量所做的一切操作都是直接对原变量的操作
参数是引用
void func(int &a) { // 传⼊的是n的引⽤,相当于直接对n进⾏了操作,只
不过在func函数中换了个名字叫a
a = 99;
}
int main() {
int n = 0;
func(n); // n由0变成了99
}
参数是变量副本
int func(int a) {// 传⼊的是0这个值,并不会改变main函数中n的值
a = 99;
return a;
}
int main() {
int n = 0;
func(n);// 并不会改变n的值,n还是0
cout<<n<<endl;
return 0;
}
STL
STL是C++的标准库,有一套功能强大的C++模板类和函数的集合,提供了一系列通用的、可复用的算法和数据结构
包括多个组件:容器、迭代器、算法、函数对象、适配器
STL之容器
容器是用来存储数据的序列,提供了不同的存储方式和访问模式
STL中的容器可以分为三类
一.序列容器:存储元素的序列,允许双向遍历
Vector:动态数组,支持快速随机访问
它的出现解决了C语言中数组的长度无法随心所欲改变的缺点。并且可以自动管理内存,非常滴好~
vector在头文件
创建vector可以不必初始化,而且如果元素不显式写出来默认都是0,就不会有像C语言那样不初始化导致错误带来的麻烦。
vector<int> myVector; // 创建一个存储整数的空 vector
vector<int> myVector(5); // 创建一个包含 5 个整数的 vector,每个值都为默认值0
vector<int> v1; v1.resize(8); //先定义⼀个vector变量v1,然后将⻓度resize为8,默认 这8个元素都是0
vector<int> myVector(5, 10); // 创建一个包含 5 个整数的 vector,每个值都为 10
vector<int> vec2 = {1, 2, 3, 4}; // 初始化一个包含元素的 vector
添加元素
myVector.push_back(7); // 将整数 7 添加到 vector 的末尾
访问元素
可以使用下表操作符[ ]或at()方法访问元素
int x = myVector[0]; // 获取第一个元素
int y = myVector.at(1); // 获取第二个元素
获取大小
size方法
int size = myVector.size(); // 获取 vector 中的元素数量
(其实string也可以用.size来获得,和.length没有区别。这只是习惯问题)
当定义一个空的vector时(即没有初始化),它的size为0
循环遍历
迭代访问
for (auto it = myVector.begin(); it != myVector.end(); ++it) {
cout << *it << " ";
}
容器vector、set、map基本上都是使用迭代器访问。
.begin()是一个指针,指向容器的第一个元素
.end()指向容器的最后一个元素的后一个位置
删除元素
erase方法
myVector.erase(myVector.begin() + 2); // 删除第三个元素
点击查看代码
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> array;//创建一个空的vector
//循环遍历:向vector中添加元素
for(int i=0;i<10;i++)
{
array.push_back(i+1);
}
//迭代器遍历:打印vector中的元素
for(auto it = array.begin();it!=array.end();it++)
{
cout<<*it<<" ";
}
cout<<"\n";
//获取vector的大小
int size=array.size();
//获取vector的特定元素
cout<<"first:"<<array[0]<<endl;
cout<<"last:"<<array.at(size-1);
cout<<"\n";
//删除vector中的元素
array.erase(array.begin()+2);
//遍历新vector
for(auto it = array.begin();it!=array.end();it++)
{
cout<<*it<<" ";
}
cout<<"\n";
//清空vector
array.clear();
cout<<"new size:"<<array.size()<<endl;
return 0;
}
队列queue
队列在头文件
队列是一种先进先出的数据结构,并且元素只能从队尾添加,只能从队首移除。
这也就意味着他无法使用下标进行元素的访问
点击查看代码
#include <iostream>
#include <queue>
using namespace std;
int main(){
//创建队列
queue<int> myQueue;
//入队,添加元素
for(int i=0;i<=10;i++){
myQueue.push(i+1);
}
//队列大小
cout<<"size:"<<myQueue.size()<<endl;
//打印首元素
cout<<"first:"<<myQueue.front()<<endl;
//打印尾元素
cout<<"last:"<<myQueue.back()<<endl;
//出队
while(!myQueue.empty()){
cout<<myQueue.front()<<" ";
//删掉首元素
myQueue.pop();
}
cout<<endl;
return 0;
}
双端队列deque
deque是一个动态数组,允许使用下标进行访问
包含在
insert(iterator pos, const T& value)
在 pos 位置插入 value 元素
pop_back()
移除容器末尾的元素
push_front(const T& value)
在容器前端添加 value 元素
点击查看代码
#include <iostream>
#include <deque>
using namespace std;
int main(){
//creat a deque
deque<int> myDeque;
//add elements to the deque,在后面添加
for(int i=0;i<10;i++){
myDeque.push_back(i+1);
}
//add elements to the front of the deque,在前面添加
for(int i=0;i<10;i++){
myDeque.push_front(i+1);
}
//print the deque
for(int i=0;i<myDeque.size();i++){
cout<<myDeque[i]<<" ";
}
cout<<endl;
//remove the first element of the deque
myDeque.pop_front();
//remove the last element of the deque
myDeque.pop_back();
//print the deque
for(int i=0;i<myDeque.size();i++){
cout<<myDeque[i]<<" ";
}
cout<<endl;
return 0;
}
list
允许在容器的任意位置快速插入和删除元素,创建时不必指定大小
提供了双向迭代器,可以向前向后遍历元素
包含在头文件中
remove(const T& val)
删除所有等于指定值的元素
sort()
排序
merge(list& other)
合并另一个已排序的链表
reverse()
反转链表
点击查看代码
#include <iostream>
#include <list>
using namespace std;
int main(){
//基本操作
//creat a list
list<int> myList;
//add elements to the list
for(int i=0;i<10;i++){
myList.push_back(i+1);
}
//print the first
cout<<"first:"<<myList.front()<<endl;
//print the last
cout<<"last:"<<myList.back()<<endl;
//print all elements
for(auto it=myList.begin();it!=myList.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//size
cout<<"size:"<<myList.size()<<endl;
//插入和删除特定元素
auto it = myList.begin();
advance(it,3);//移动迭代器到第四个元素
myList.insert(it,11);//在第四个元素前插入11
myList.erase(it);//删除第四个元素
it = myList.begin();
advance(it,2);
myList.insert(it,8);
myList.erase(it);
for(auto it=myList.begin();it!=myList.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//排序
myList.sort();
myList.unique();//删除相邻元素
for(auto it=myList.begin();it!=myList.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//合并
list<int> myList2={5,8,6,13,1};
myList2.sort();//确保合并的是两个已排序的链表
myList.merge(myList2);
for(auto it=myList.begin();it!=myList.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//反转
myList.reverse();
//打印
for(auto it=myList.begin();it!=myList.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//交换
list<int> myList3={1,2,3,4,5};
myList.swap(myList3);
for(auto it=myList.begin();it!=myList.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//删除所有等于特定元素值的元素
myList.remove(5);
for(auto it=myList.begin();it!=myList.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
三种序列容器对比(来源于C++)
二.关联容器:存储键值对,每个元素都有一个键(key)和一个值(value),并且通过键来组织元素
集合set
集合set存储了一组唯一的元素,并按照一定的顺序进行排序
是基于红黑树实现的,因此具有对数时间复杂度
set容器中存储的元素类型必须满足两个条件:
1.可以比较大小
2.可以被复制和赋值
find方法
返回一个迭代器
如果找到某元素,返回迭代器指向该元素的位置
未找到,则指向容器的end()
以下代码展示了常见用法嘞~
#include <iostream>
#include <set>
using namespace std;
int main(){
//creat
set<int> mySet;
//insert
mySet.insert(18);
//input
cout<<"first:"<<*(mySet.begin())<<endl;
//insert
for(int i=0;i<10;i++){
mySet.insert(i+2);
}
//output
for(auto it =mySet.begin();it!=mySet.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//find
if(mySet.find(18)!=mySet.end()){
cout<<"find 18"<<endl;
//打印迭代器的位置
cout<<"position:"<<distance(mySet.begin(),mySet.find(18))<<endl;
}
else{
cout<<"not find 18"<<endl;
}
//erase
mySet.erase(18);
//size
cout<<"size:"<<mySet.size()<<endl;
//now,此时18就找不到喽~
cout<<(mySet.find(18)!=mySet.end())<<endl;
return 0;
}
多重集合multiset
映射map
map是键值对,每个键都是唯一的
map会自动将所有的键值对按照键从小到大排序
map提供了双向迭代器,可以向前向后遍历元素
以下代码展示了常见用法~
#include <iostream>
#include <map>
using namespace std;
int main(){
//create a map
map<string,int> myMap;//定义一个空的map myMap,键是string类型,值是int类型
//add
myMap["hello"]=2;//将键设为“hello”,值设为2
//print
cout<<myMap["hello"]<<endl;//访问myMap中键为“hello”的值,如果键不存在,则返回0
cout<<myMap["world"]<<endl;
myMap["world"]=3;
myMap[","]=1;
//print all elements
for(auto it=myMap.begin();it!=myMap.end();it++){
//用迭代器遍历,输出map中所有的元素
//key用it->first获取,value用it->second获取
cout<<it->first<<" "<<it->second<<endl;
}
//size
cout<<"size:"<<myMap.size()<<endl;
//访问第一个元素
cout<<myMap.begin()->first<<" "<<myMap.begin()->second<<endl;
//访问最后一个元素
cout<<myMap.rbegin()->first<<" "<<myMap.rbegin()->second<<endl;
//检查键是否存在
if(myMap.find("chunlei")!=myMap.end()){
cout<<"chunlei"<<endl;
}
else{
cout<<"can't find chunlei"<<endl;
}
//删除元素
myMap.erase(",");
cout<<"size:"<<myMap.size()<<endl;
//清空
myMap.clear();
cout<<"size:"<<myMap.size()<<endl;
return 0;
}
多重映射multimap
三.无序容器(C++11引入):哈希表,支持快速查找、插入和删除
unordered_map
和unordered_set
分别在头文件<unordered_map>
和<unordered_set>
中
unordered_map和map(unordered_set和set)的区别是:map会按照键值对的键进行排序,而无序容器省去了排序的过程
如果偶尔用map/set刷题超时了,可以考虑用无序容器,或许可以缩短时间提高效率,至于用法和map/set是一样的
栈stack的使用
stack在头文件<stack>
中,实现了一个先进后出的数据结构。适用于需要“最后添加的元素最先被移除”
栈的元素是线性排序的,但只允许在一端进行添加和移除操作
注意:栈不提供直接访问元素的方法,只能通过top()访问栈顶元素
点击查看代码
#include <iostream>
#include <stack>
using namespace std;
int main(){
//create a stack
stack<int> myStack;
//push
for(int i=0;i<6;i++){
myStack.push(i+1);
}
//访问栈顶元素
cout<<myStack.top()<<endl;
//获取大小
cout<<myStack.size()<<endl;
//移除栈顶元素
myStack.pop();
//打印所有元素
while(!myStack.empty()){
cout<<myStack.top()<<" ";
myStack.pop();
}
return 0;
}
bitset
提供了一种方式来操作固定大小的位集合。是一个由位组成的集合,每个位可以是0或1
可以用来处理二进制,非常之方便
在头文件
点击查看代码
#include <iostream>
#include <bitset>
using namespace std;
int main(){
bitset<5> b("1101");//5表示5个二进位
//初始化方式:
//bitset<5> b;都为0
//bitset<5> b(u);u为int类型,如果u=3,则输出b的结果为00011
//bitset<8> b(s);s为字符串,如“1101”,输出结果是00001101,在前面补0
//bitset<8> b(s,pos,n);从字符串的s[pos]开始,n位长度
cout<<b<<endl;
for(int i=0;i<5;i++){
cout<<b[i];
}
cout<<endl;
//注意,bieser相当于一个数组,但是他是从二进制的低位到高位分别为b[0],b[1]...的
//所以,按照b[i]的方式输出和直接输出是有区别的
//所以,对于上面第一种打印方式,是正常的二进制顺序
//对于第二种,是正常二进制顺序的倒序
//修改位
b[3]=0;//把下标是3的位置改为0
cout<<b<<endl;//输出结果是00101
b.set(4);//把下标是4的位置改为1
cout<<b<<endl;
b.reset(0);//把下标是0的位置改为0
cout<<b<<endl;
b.reset();//所有位归零
cout<<b<<endl;
b.flip();//b的二进制逐位取反
cout<<b<<endl;
cout << endl << b.any(); //b中是否存在1的⼆进制位
cout << endl << b.none(); //b中不存在1吗?
cout << endl << b.count(); //b中1的⼆进制位的个数
cout << endl << b.size(); //b中⼆进制位的个数
cout << endl << b.test(2); //测试下标为2处是否⼆进制位为1
cout<<endl;
bitset<8> b1("10101010");
bitset<8> b2("11110000");
//位与操作
bitset<8> b_and=b1&b2;
cout<<"AND: "<<b_and<<endl;
//位或操作
bitset<8> b_or=b1 | b2;
cout<<"OR: "<<b_or<<endl;
//位异或操作
bitset<8> b_xor=b1^b2;
cout<<"XOR: "<<b_xor<<endl;
//位非操作
bitset<8> b_not=~b1;
cout<<"NOT: "<<b_not<<endl;
return 0;
}
CPP算法库
提供了一组用于操作容器的算法,包括排序、搜素、复制、比较等
大多数
algorithm_name(container.begin(), container.end(), ...);
第一个参数是容器的起始位置,第二个参数是结束位置的后一个位置,第三个及以后得参数是一些自定义函数
sort函数
在头文件algorithm
中,主要是对一个数组进行排序(array/vector均可)
点击查看代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
//cmp函数返回的值是bool类型
//定义了从大到小的排序规则
bool cmp(int a,int b){
return a>b;
}
int main(){
//vector
vector<int> v(10);
for(int i=0;i<10;i++){
cin>>v[i];
}
//没有使用cmp参数,所以按照默认的从小到大排序
sort(v.begin(),v.end());
for(auto it=v.begin();it!=v.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//array
int array[10];
for(int i=0;i<10;i++){
cin>>array[i];
}
//使用cmp函数作为参数,所以是从大到小排序
sort(array,array+10,cmp);
for(int i=0;i<10;i++){
cout<<array[i]<<" ";
}
cout<<endl;
return 0;
}
使用sort自定义cmp函数
//cmp最好用的是在结构体中
//在这个程序,我们尝试实现这样一种功能:将学生成绩进行从大到小排序。如果成绩相同则按学号从小到大排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Stu{
int number;
int score;
Stu(int number,int score):number(number),score(score){
}
};
//定义排序规则
bool cmp(Stu a,Stu b){
return a.score!=b.score ? a.score>b.score :a.number<b.number;
}
int main(){
//定义结构体数组
//这里每一个Stu初始化后是逗号,别问我为什么强调这个蠢问题
//然后要记得vector写完之后加分号,同样别问我为什么强调这个
vector<Stu> stu={
Stu(1,78),
Stu(2,72),
Stu(3,78),
Stu(4,92),
Stu(5,38),
};
sort(stu.begin(),stu.end(),cmp);
for (auto it=stu.begin();it!=stu.end();it++) {
cout << "number: " << it->number << ", score: " << it->score << endl;
}
return 0;
}
头文件
cctype本质上来源于C语言标准库中的头文件ctype.h
这个头文件可以判断某个字符是字母、数字还是其他字符
isalpha
字母(包括大小写)
islower
小写字母
isupper
大写
isalnum
字母大小写+数字
isblank
space和\t
isspace
( space 、\t 、\r 、\n )
还可以转换大小写
tolower
、toupper
C++11新增超好用特性
auto声明
auto
是C++11里面的新特性,可以让编译器根据初始值类型直接推断变量的类型
比如:
auto x = 100; // x是int变量
auto y = 1.5; // y是double变量
但是,auto在算法中最主要的可以在使用迭代器时语法更简洁
// 本来set的迭代器遍历要这样写:
for(set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
// 现在可以直接替换成这样的写法:
for(auto it = s.begin(); it != s.end(); it++) {
cout << *it << " ";
}
简直不要太清爽!!!
基于范围的for循环
除了像C语言中的for形式外,C++11标准提供了基于范围的for循环
比如:
//读取
int arr[4] = {0, 1, 2, 3};
for (int i : arr)
cout << i << endl; // 输出数组中的每⼀个元素的值,每个元素占据⼀⾏
//修改
int arr[4] = {0, 1, 2, 3};
for (int &i : arr) // i为引⽤变量
i = i * 2; // 将数组中的每⼀个元素都乘以2,arr[4]的内容变为了{0, 2, 4, 6}
//与auto、容器的结合使用
//v是⼀个int类型的vector容器
for (auto i : v)
cout << i << " ";
to_string
在头文件
作用是把其他类型的变量转换成字符串
string s1 = to_string(123); // 将123这个数字转成字符串
stoi、stod
在
#include <iostream>
#include <string>
using namespace std;
int main() {
string str = "123";
int a = stoi(str);
cout << a;
str = "123.44";
double b = stod(str);
cout << b;
return 0;
}
暂时想到的就这么多了...
cpp博大精深,STL还要越练越熟悉呐~