目录
前言
用C++做题的好处
using namespace std
cin,cout头文件
变量声明
bool变量
const定义常量
string类
结构体
引用&
vector
set
map(键值对)
stack(栈)
queue(队列)
unordered_map和unordered_set(无序键值对和无序集合)
C语言是一门很强大的编程语言,刚学完了C语言为了进阶,有着刷更多算法题的需求,并且在使用C语言的过程中,有很多繁琐的步骤。因此我在此记录C语言在进阶C++的过程中所需要学习的内容,让我可以在由C语言进阶C++的过程中巩固,提高C++的熟练度。
为什么要用C++来刷算法题呢,用C语言的过程中,写代码是很繁琐的,要用一些数据结构、栈、队列,这些都是要自己用C语言来实现,会花费很多的时间,而在C++中,可以直接调用STL库中的栈和队列,大幅地提高了做题的效率,同时有很多的工具。并且在此之上,C++是完全兼容C语言的,可能会有一些细微的差别,但差别并不大,再者string类对字符串的处理很好用,但在实现相同的功能时,C++的速度可能会稍慢与C语言,例如使用cin和cout进行输入输出与scanf和printf相比会稍慢一些,但更便利。
#include
using namespace std;
int main(void)
{
int n;
cin >> n;
cout << "woaini" << ' ' << n << endl;
return 0;
}
1.头文件iostream为输入输出流,可以相当于C语言中的stdio.h,是一个必须的头文件
2.using namespace的意思是使用名称空间,该空间名称便为std为标准输入输出,using namespace std;代表的意思就是使用std这个命名空间。为什么要使用命名空间呢,因为不同厂商在建立函数时可能会有函数名重复的情况,为避免这种情况,引用命名空间就可以只使用该名称空间下的函数,上文代码中的cin、cout就是std名称空间中的函数。
3.这里cin为输入函数后面需接">>",表达的意思为输入一个值赋予n,cout为输出函数后面需接"<<",表达的意思为输出"<<"后面的参数,作用分别相当于C语言中的scanf和printf,不过这里的输入不用格式化输入来表示常量类型,也不用“&”,更加简洁。
4.endl表示的是end of line起到换行的作用作用相当于"\n",
1.cin和cout在使用时的确会更方便,但是由于不用输入格式化输出和输入,所以在使用时速度会稍慢于scanf和printf。
2.C++的头文件与C语言的不同在于C语言在调用头文件时要在头文件后面加上".h",而C++只需在头文件前面加上“c”即可,如:#include
C++的变量声明相较于C语言使用更加的便利,C++可在函数的任何地方进行定义,其中最明显的体现在for循环中i的声明
以下为C++中变量声明
#include
using namespace std;
int main(void)
{
for (int i = 0; i < 10; i++)
cout << a << ' ';
return 0;
}
以下为C语言中的变量声明
#include
int main(void)
{
int i;
for (i = 0; i < 10; i++)
printf("a ");
return 0;
}
将以上两段代码对比便可得知在变量声明上的区别。
bool变量是C++特有的一种新类型变量,有两个值非0为ture、0为false,接下来引入一段代码以便于对bool变量有更深入的理解
#include
using namespace std;
int main(void)
{
bool b1 = true;
bool b2 = false;
bool b3 = -1;
cout << b1 << ' ' << b2 << ' ' << b3;
return 0;
}
在C语言中被const定义的称为常变量,那他为什么成为常变量而不称为常量呢?因为C语言中被const所定义的常变量虽然不能改变其值,但是不能用于定义一个确定长度的数组,所以本质上还是变量。而在C++中const所定义的是常量可以用于定义一个确定长度的数组,所以const的作用类似#define
1.定义
string a = "I can understand your meanning.";
string b = "But I don't know what I should do.";
2.拼接
在C++中string类字符串可直接进行拼接
string sub = a + b;
这里字符串b会拼接到字符串a的后面
3.输入(出)
#include
using namespace std;
int main(void)
{
string a,b;
cout << "请依次输入字符串a,b";
cin >> a >> b;
string sub = a + b;
cout << a << endl << b << endl << sub;
return 0;
}
这里的输入用了cin,但此次输入在遇到空格或者TAB时会结束此次输入故可以引用 getline(cin,a)来输入一整行的字符串遇到回车结束
4.处理
(1).s.length可以获取字符串s的长度
(2).
#include
using namespace std;
int main(void)
{
string a= "Don't lose yourself.";
string a_sub1 = a.substr(6, 4);
string a_sub2 = a.substr(6);
cout << a_sub1 << endl << a_sub2;
return 0;
}
a.substr(n,m)的作用是返回字符串a第n个字符后m个字符所组成的新字符串,此功能也有另一种使用方法a.substr(n)省去m便是返回字符串a第n个字符后所有的字符所组成的新字符串。
在C语言中定义一个结构体变量是,前面要加上struct,而在C++中可以直接用结构体名定义结构体变量,在下方代码中便有此体现
#include
using namespace std;
struct stu
{
int No;
string name;
};
int main(void)
{
stu student;
return 0;
}
在C++中的引用&与C语言中的取地址符&没有任何关系,注意不要弄混,使用形式为int &a,接下来引入一段代码
#include
using namespace std;
void add_10(int& a);
int main(void)
{
int a = 5;
add_10(a);
cout << a;
return 0;
}
void add_10(int& a)
{
a += 10;
}
在这段代码中add_10函数引用a调用的就是实参,省去了c语言需要传地址和接地址的麻烦。
1.头文件:#include
2.创建数组:创建vector数组有三种形式
vector a;
vector b(5);
vector c(5, 4);
a数组没有设定大小,b便定义为可以存放5个int类变量的数组,c定义为存放5个int类变量,每个变量的值为4。没有被初始化的数据默认为0。
3.处理
接下来引入一段代码对vector数组进行详解
#include
#include
using namespace std;
int main(void)
{
vector a(5, 4);
a.resize(10);
a.push_back(11);
for (auto p = a.begin(); p != a.end(); p++)
cout << *p << ' ';
return 0;
}
(1)a.resize(n)的作用为重新分配数组大小为n
(2)a.pushback(data)的作用为在数组a的结尾追加数据data
(3)迭代器
for (auto p = a.begin(); p != a.end(); p++)
cout << *p << ' ';
迭代器的作用可以将数组中的所有元素输出,其中p为指针变量,要用指针变量的使用方法对其进行使用。a.begin()的返回值为数组第一个元素的地址,a.end()的返回值为最后一个元素的下一个地址。
1.set是集合,它里面的元素各不相同,而且元素会按照从小到大排序
2.头文件:#include
3.创建集合:set
注:a的后面不可以加内容
4.处理
接下来引入一段代码对set的处理进行详解
#include
#include
using namespace std;
int main(void)
{
seta;
a.insert(5);
a.insert(3);
a.insert(4);
a.insert(2);
for (auto p = a.begin(); p != a.end(); p++)
cout << *p<<' ';
cout << endl;
a.erase(3);
for (auto p = a.begin(); p != a.end(); p++)
cout << *p << ' ';
cout << endl;
cout << (a.find(3) != a.end()) << ' ' << (a.find(4) != a.end());
return 0;
}
此段代码的运行结果为
(1).插入:a.insert(n):将n的值插入集合a
(2).删除:a.erase(n):删除集合a中的n
(3).遍历:集合中的所有元素可以用迭代器遍历
for (auto p = a.begin(); p != a.end(); p++)
cout << *p << ' ';
(4).查找:a.find(n):查找集合a中是否有n,其返回值为指针,这里的(a.find(3) != a.end())和(a.find(4) != a.end())实际上都是bool值,分别为false和ture,故返回值分别为0和1。
1.map是键值对,它会自动将所有的键值从小到大排序,其中排序的规则类似于C语言string库中的函数strcpm,通过从前往后对字符串中字符的ASC码值大小进行比较排序。
2.头文件#include
3.创建键值对:
map a;
其中string为键,int为值,成对故称为键值对。
4.处理
接下来引入一段代码对键值对进行详细解读
#include
#include
(1)添加:添加键值对采用下面这种方式,其中的键用'[ ]'包含由于键为字符串故用" "包含在其后用'='连接对应的值
a["you"]=1;
(2)访问:
cout << a["hello"]//访问
其中输出结果为该键所对应的值。
(3).遍历:
for (auto p = a.begin(); p != a.end(); p++)//运用迭代器输出该键值对中所有的值
cout << p->first << ':' << p->second << endl;//输出键值对,输出方式类似结构体
这里在输出键值对的时候用的不是*p而是p->实际上是因为map(键值对)是以结构体类型进行定义,故获取方式类似于结构体指针,map可以看作为
typedef struct
{
string first;
int second;
}map;
(4). 获取长度
cout << a.size() << endl;
用size()来获取键值长度,其长度由键值对个数决定,一个键值对占一个字节。
1.在C语言中,数据结构中会接触栈,其特点为先入后出
2.头文件:#include
3.创建栈:stack
4.处理:下面引入一段代码对stack(栈)进行详细解释
#include
#include
using namespace std;
int main(void)
{
stack a;//创建栈
a.push(5);//压栈
a.push(4);//压栈
a.push(7);//压栈
a.pop();//出栈
a.push(75);//压栈
cout << a.top() << endl;//访问栈顶
cout << a.size() << endl;//获取栈顶长度
return 0;
}
(1).压栈
a.push(5);//压栈
此操作将5压入栈中
(2).出栈
a.pop();//出栈
此操作将栈顶元素删除
(3).访问栈
cout<
此操作访问栈顶元素
(4).获取栈项长度
cout<
此操作与前文一样运用size()获取长度,根据上文代码,此栈长度应为3.
5.注:栈可以通过size()获取长度,但是不能够通过迭代器获取全部元素
1.队列的特点与栈相反,先进先出,后进后出,但是栈只能获取栈顶元素,而队列可以获取队首和队尾元素
2.头文件:#include
3.创建队列:queue
4.处理:接下来引入一段代码对队列进行详细解释
#include
#include
using namespace std;
int main()
{
queue a;//创建队列
for (int i = 0; i < 10; i++)
a.push(i);//入队
cout << "队首为:" << a.front() << "队尾为:" << a.back()<
(1).入队:a.push(i)
(2).出队:a.pop()
(3).访问队首:a.front()
(4).访问队尾:a.back()
(5).获取长度:a.size()
5.注:队列与栈一样不能用迭代器遍历,但是可以用size()获取长度。
1.unordered_map和unordered_set其实就是无序的键值对和集合,若做题时超时,并且对元素的顺序没有要求便可以使用。
2.头文件:#include
#include
3.map和set的使用在前文已经介绍过了接下来引入一段代码对unordered_map和unordered_set进行详解
#include
#include
#include
using namespace std;
int main(void)
{
unordered_map m;
unordered_set s;
s.insert(5);
s.insert(4);
s.insert(1);
s.insert(7);
m["i"] = 5;
m["you"] = 7;
m["x"] = 8;
m["love"] = 6;
for (auto p = s.begin(); p != s.end(); p++)
cout << *p << ' ';
cout << endl;
for (auto p = m.begin(); p != m.end(); p++)
cout << "键:" << p->first << "值:" << p->second << endl;
return 0;
}
可以发现通过迭代器输出的键值对和集合为乱序,其顺序的确定包含其他方面的知识,再此不过多赘述。