基础篇
using namespace std
总体框架和注释
#include<iostream> //输入输出流 类比于C语言里的<stdio.h>头文件 是必备的一个文件
using namespace std;
//使用std这个名称空间 不同厂商定义的函数彼此之间可能会重复,为避免将函数都封装在各自的名称空间内,
//使用时就在main函数前面说明用了什么名称空间,这样的话可以避免一些不必要的冲突
int main (void)
{
int n;
cin >> n; //输入,等价于scanf("%d",&n);
cout << "jxynb!" << ++n << endl;
//endl就是换行符的意思,等价于"\n"
//此处cin cout endl全部杯封装在std这个名称空间里面,故而没有上面这句话程序是运行不了的
//但删除后这样写也是合理的
// std::cin>>n;
// std::cout<<"jxynb!",,__n<<std::endl ;
return 0;
}
测试一:
#include<iostream>
using namespace std;
int main (void)
{
int n;
cin >> n;
cout << "jxynb!" << ++n <<endl;
return 0;
}
测试二:
#include<iostream>
//using namespace std;
int main (void)
{
int n;
std::cin >> n;
std::cout << "jxynb!" << ++n <<std::endl;
return 0;
}
测试三:
#include<iostream>
using namespace std;
int main (void)
{
int n;
cin >> n;
cout << "jxynb!" << n++ << "\n";
return 0;
}
cin和cout
#include<iostream>
#include<cstring> //删去最后的.h在最前面加c
using namespace std;
int main (void)
{
int n;
cin >> n; //输入
cout << "jxynb!" << ++n <<endl; //输出
return 0;
}
头文件
#include<iostream>
#include<cstring> //如果想要调用类比于#include<string.h>或者#include<math.h>
#include<cmath>
using namespace std;
int main (void)
{
int n;
cin >> n;
cout << "jxynb!" << ++n <<endl;
return 0;
}
变量声明
可以在for循环中进行变量声明,虽然C99以后都可以了。
#include<iostream>
using namespace std;
int main(void)
{
int n;
cin >> n;
for(int i=0; i<10; i++)
cout << n << " ";
cout << endl;
for(int i=0; i<10; i++)
cout << n+1 << " ";
return 0;
}
输入5以测试
bool变量
非0为true,0为false,虽然c99之后同样也可以了
#include<iostream>
using namespace std;
int main(void)
{
bool flag = true;
bool flag2 = -1;
bool flag3 = 0;
cout << flag << " " << flag2 << " " << flag3 << endl;
return 0;
}
应该会输出 1 1 0
const定义常量
类比于C语言宏定义(#define),定义了一个不能改变的常量
测试一
#include<iostream>
using namespace std;
//#define MAX 150
int main(void)
{
const int MAX = 150;
cout << MAX << endl;
return 0;
}
输出150;
测试二
#include<iostream>
using namespace std;
//#define MAX 150
int main(void)
{
const int MAX = 150;
MAX = 100;
cout << MAX << endl;
return 0;
}
编译器会报错(不会输出100),所以用const定义的一个常量的值是不能被改变的
string 类
定义+拼接
#include<iostream>
using namespace std;
int main(void)
{
string s = "hello";
string s2 = " world!"; //比如定义字符串类型
string s3 = s + s2; //相加就可以进行拼接
cout << s3 << endl;
return 0;
}
输入(出)
测试一:
#include<iostream>
using namespace std;
int main(void)
{
string s = "hi";
string s2 = " world!"; //比如定义字符串类型
string s3 = s + s2; //相加就可以进行拼接
cin >> s;
cout << s << " world!" << endl;
return 0;
}
此处输入hello测试,得到hello world!
测试二:
#include<iostream>
using namespace std;
int main(void)
{
string s = "hello";
string s2 = " world!"; //比如定义字符串类型
string s3 = s + s2; //相加就可以进行拼接
cin >> s;
cout << s << endl;
return 0;
}
但如果输入hello world!,便只会读取hello,故而输出只有hello。(cin只能输入一个单词)
测试三
为解决测试二中cin只能输入一个单词的问题问题,调用getline
#include<iostream>
using namespace std;
int main(void)
{
string s = "hi";
string s2 = " world!"; //比如定义字符串类型
string s3 = s + s2; //相加就可以进行拼接
getline(cin,s) //cin >> s;
cout << s << endl;
return 0;
}
getline就是获取一行的意思,可以把一行输入的整个字符串全部输入到程序里
可以再次测试输入hello world!
处理
比方说想获取字符串长度
#include<iostream>
using namespace std;
int main(void)
{
string s = "hi";
string s2 = " world!"; //比如定义字符串类型
string s3 = s + s2; //相加就可以进行拼接
getline(cin,s) //cin >> s;
cout << s << endl;
cout << s.length() << endl; //针对s.lenth(),s理解为对象,length理解为方法
return 0;
}
输入hello world!测试,长度为12
比方说对子串的处理
#include<iostream>
using namespace std;
int main(void)
{
string s = "hello world!";
cout << s << endl;
string s_sub = s.substr(6,5); //表示从下标为6的字符开始取,取五个字符
string s_sub = s.substr(6); //表示从下标为6开始,将其中所有字符都拷贝到子串当中
cout << s_sub << endl;
return 0;
}
结构体
可以省去struct
#include<iostream>
using namespace std;
struct stu
{
string name;
int age;
};
int main(void)
{
stu a[10]; //C语言中struct stu a[10];省去了以前用typedef定义以后重命名带来的麻烦
return 0;
}
引用&传值
c++里面的引用和C语言里的“&”没有任何关系,不要混淆;
也理解一下C语言的传参,解决了C语言中误用指针所带来的麻烦。(好好理解)
#include<iostream>
using namespace std;
void c(int &a)
{
a += 1;
}
int main(void)
{
int a = 4;
c(a);
cout << a << endl;
return 0;
}
引用时会把初始变量里面的值改变的
输入4,会输出5;
#include<iostream>
using namespace std;
void c(int a)
{
a += 1;
}
int main(void)
{
int a = 4;
c(a);
cout << a << endl;
return 0;
}
去掉引用的&输入4输出的还是4
STL篇
以下在c++中都叫做容器,容器肯定有大小,故而有resize的概念,用resize来获取
vector
理解为动态数组或者不定长(可变长)的数组(借助matlab中数组都是以向量形式来运算的),故而向量也是一种理解
头文件
#include <vector>不要漏
更不要漏名称空间(vector也存在于这个名称空间内,缺了vector起不了作用)
#include<iostream>
#include<vector> //vector也存在于下一行这个名称空间里
using namespace std;
int main(void)
{
string s;
s.length(); //变量名+方法
vector <int> a(10,2);
a.size(); //变量名+方法
return 0;
}
创建数组
测试一
vector int v; 定义了一个空的数组v
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
vector <int> v; //定义了一个数组v,此时数组为空,长度为0
cout << v.size() << endl;
return 0;
}
输出0
测试二
v.resize();
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
vector <int> v; //定义了一个数组v,此时数组为空,长度为0
//没有意义故追加元素
v.resize(10); //重新分配空间,v.resize(length)
//cout << v.length() <<endl; 错了
cout << v.size() <<endl;
return 0;
}
输出10
测试三
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int main(void)
{
vector <int> v; //定义了一个数组v,此时数组为空,长度为0
//没有意义故追加元素
v.resize(10); //重新分配空间
//追加数据 此处分配的是元素数量还是字节长度:元素数量
for (int i=0;i<10;i++)
{
v[i] = i;
}
for (int i = 0; i < 10; i++)
cout << v[i]<< " " << endl;
cout << v.size() << endl;
return 0;
}
输出
0
1
2
3
4
5
6
7
8
9
10
也可以
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
vector <int> v; //定义了一个数组v,此时数组为空,长度为0
//没有意义故追加元素
v.resize(10); //重新分配空间
//追加数据
for (int i=0;i<10;i++)
{
v[i] = i;
}
for (int i = 0; i < 10; i++)
cout << v[i] << " ";
return 0;
}
输出
0 1 2 3 4 5 6 7 8 9
测试四
vector<int> v(10,2);
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
vector<int> v(10,2); //给数组v分配了10个空间,值都初始化为2
for (int i=0; i<10; i++)
cout << v(i) << " ";
rerurn 0;
}
输出
2 2 2 2 2 2 2 2 2 2
c++数组初始化的时候,分配的空间里面初始化都为0
分配数组大小
vector<int> v(10);
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
vector<int> v;
v.resize(10); //resize初始化以后的空间里面附的值也是0
//上方两行等价于vector<int> v(10,0);等价于vector<int> v(10);
for (int i=0; i<10; i++)
cout << v(i) << " ";
rerurn 0;
}
输出
0 0 0 0 0 0 0 0 0 0
末尾添加新的数据 接测试三
v.push_back(data)
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
vector <int> v; //定义了一个数组v,此时数组为空,长度为0
//没有意义故追加元素
v.resize(10); //重新分配空间,不会溢出,10个空间有11个数
//追加数据
for (int i=0;i<10;i++)
{
v[i] = i;
}
v.push_back(11);//直接放入想要附的值, 变量+方法+括号内是否需要参数
for (int i = 0; i < 11; i++)
cout << v[i] << " ";
return 0;
}
输出
0 1 2 3 4 5 6 7 8 9 11
迭代器
理解为遍历,把一个数组里面所有的元素都给遍历一遍,这个时候不用去考虑开头和结束
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
vector<int> v;
v.resize(10);
for(auto p=v.begin();p!=v.end();p++) //p看作一个指针
cout << *p << " ";
return 0;
}
运行后发现和for循环具有给定了一个循环变量的for循环是一样的效果
若在后面追加元素
#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
vector<int> v;
v.resize(10);
v.push_back(11);
for(auto p=v.begin();p!=v.end();p++)
cout << *p << " ";
return 0;
}
begin()指向容器第一个元素,不是索引为0的元素
如1 2 3 4 5 8 ,则begin()指向1 而end()指向8的后一个位置(数组中最后一个元素的下一个位置)
即自动把容器里面所有数据都遍历一遍,不像带循环变量的for循环需要自己去找和确认边界
set
翻译为组和集合的意思,里面的元素各不相同,而且元素会按照从小到大排序
头文件
#include<set>
创建集合
和数组的创建非常相似 set <int> s; s的后面不可以加内容
测试一:
#include<iostream>
#include<vector>
#include<set>
using namespace std;
int main(void)
{
set <int> s;
//vector<int> sl(10,2); 与数组的创建很类似,但set的集合和咱们的数组不同,s后面不能带任何参数进去
s.insert(1);
s.insert(2);
s.insert(3);
for (auto p=s.begin();p!=s.end();p++)
{
cout << *p << " "; //p指针所指向元素
}
cout << endl;
cout << (s.find(2) != s.end()) << endl;
cout << (s.find(4) != s.end()) << endl;
s.erase(1);
cout << (s.find(1) != s.end()) << endl;
return 0;
}
运行是没有问题的
如果想在s后面附一段空间,如set <int> s(10); 编译后会发现报错 关于这一点的理解:给一个集合分配了10的空间,但是它没有元素就是有问题的,从数学角度来看集合里一定有元素,并且元素之间是两两互异的;如果成功分配了10的空间且按照初始化都为0,即一个集合里有10个0这样显然是错的,不符合集合定义,即使初始化为set <int> s(10,2);也是不满足互异的条件。因此只能为set <int> s;
处理
插入
创建集合后就要对它进行处理,一个集合里面没有任何元素,因此我们要插入元素。
s.insert(data);
遍历
迭代器
查找
s.find(data); s.find()返回值是一个 指针
删除
s.erase(data);
#include<iostream>
#include<vector>
#include<set>
using namespace std;
int main(void)
{
set <int> s;
//vector<int> sl(10,2); 与数组的创建很类似,但set的集合和咱们的数组不同,s后面不能带任何参数进去
s.insert(2);
s.insert(1);
s.insert(3);
for (auto p=s.begin();p!=s.end();p++)
{
cout << *p << " ";
}
cout << endl;
cout << (s.find(2) != s.end()) << endl;
// (s.find(2) != s.end())这一块其实是一个布尔值,即比较两者是否相等
// 对于1 2 3,找到了将2的地址返回给方法
// 这个方法的返回值是指针,比较与3后面的s.end()是否相等
// 此处不相等整个的布尔值为1。判断存在返回1,不存在返回0
cout << (s.find(4) != s.end()) << endl;
s.erase(1);
cout << (s.find(1) != s.end()) << endl;
return 0;
}
观察输出发现即使插入数据不是从小到大,在set下输出也会是从小到大
map(键值对)
map(是键值对,它会自动将所有的键值对按照从小到大排序)
头文件
#include <map>
创建键值对
map <string,int> m; string即对字符串首字符的ASCII码,若相同则比较第二个
#include<iostream>
#include<map>
using namespace std;
int main(void)
{
map <string, int> m; //键是string类型,值是整型
m["hello"] = 2; //用m像数组一样调用它
m["world"] = 3;
cout << "hello: " << m["hello"]; //在知道了有什么元素的前提下直接输出;先输出键,再输出值
return 0;
}
遍历
有一个问题,若已经创立了键值对但是不知道它里面有哪些字符串,所以接下来可以使用迭代器