STL(Standard Template Library)标准模板库
STC从广义上分为:容器,算法(algorithm),迭代器。容器和算法之间通过迭代器进行无缝连接
一句话STL牛皮,大兄弟。
第一种遍历:
先可以将迭代器理解成指针
#include<iostream>
#include<vector>
using namespace std;
void test()
{
vector<int>v; //声明一个名为v的容器,这个容器存放int型数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
vector<int>::iterator itbegin = v.begin(); //定义向量迭代器指向容器的起始位置
vector<int>::iterator itend = v.end(); //这里的end()指的是最后一个数的下一个位置
while (itbegin != itend)
{
cout << *(itbegin++) << endl;
}
}
int main()
{
test();
return 0;
}
第二种遍历:
#include<iostream>
#include<vector>
using namespace std;
void test()
{
vector<int>v; //声明一个名为v的容器,这个容器存放int型数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << endl;
}
}
int main()
{
test();
return 0;
}
第三种算法遍历:
#include<iostream>
#include<vector>//容器头文件
#include<algorithm>//算法头文件
using namespace std;
void myprintf(int v)
{
cout << v << endl;
}
void test()
{
vector<int>v; //声明一个名为v的容器,这个容器存放int型数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
for_each(v.begin(), v.end(), myprintf);//myprintf自定义的一个回调函数,具体步骤可查看源码
}
int main()
{
test();
return 0;
}
自定义数据类型的遍历:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class person
{
public:
person(string name ,int ages)
{
this->ages = ages;
this->name = name;
}
int ages;
string name;
};
void test()
{
person p1("大头儿子", 10);
person p2("小头爸爸", 50);
person p3("围裙妈妈", 25);
person p4("隔壁老王", 28);
vector<person>v;
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
//这里必须强调一下(*it),it就是指向begin的指针,那么*it就是你所定义的对象,不解引用的话可以直接->操作
for (vector<person>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << (*it).name << " " << it->ages << endl;
}
}
int main()
{
test();
return 0;
}
//容器的嵌套
#include<iostream>
using namespace std;
#include<vector>
void test()
{
//先定义一个嵌套的容器,可以类比教学楼里面的教室
vector<vector<int>>v;
//在定义内层的容器,我们这里定义三个就可以了
vector<int>v1;
vector<int>v2;
vector<int>v3;
//先对最内层容器赋值
for (int i = 0; i < 5; ++i)
{
v1.push_back(i);
v2.push_back(10 + i);
v3.push_back(100 + i);
}
//接着拿小容器给大容器赋值
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
//接着我们尝试打印一下容器里面的数据
//打印也是从小容器开始打印的
for (vector<vector<int>>::iterator it1 = v.begin(); it1 < v.end(); ++it1)
{
for (vector<int>::iterator it2 = (*it1).begin(); it2 != (*it1).end(); ++it2)
{
cout << (*it2) << " ";
}
cout << endl;
}
}
int main()
{
test();
return 0;
}
string容器的基本概念:
char*是一个指针,string是一个类,string封装了一个char*来管理这个字符串,是一个char*类型的容器
string()构造:
string()创建一个空字符串
string(const char* s)使用一个字符串来初始化
string(const string& str)使用一个string字符串区初始化另外一个string类型的字符串
string(int n,char c)用字符c初始化n个字符,
#include<iostream>
using namespace std;
#include<string>
void test()
{
string(); //string 就是一个类,然后string()就相当于string p1()但是没有初始化
string p4("万绍"); //使用一个字符串来初始化
string p2(10, 'c'); //用字符c初始化n个字符,
string p1("康熙");
string p3(p1);
cout << p2 << endl;
cout << p3 << endl;
}
int main()
{
test();
return 0;
}
string基本赋值操作:
string内部已经给出很多的运算符的重载
//结合上图看
#include<iostream>
using namespace std;
#include<string>
void test()
{
string p1; //定义一个空字符串
char *c = "吃了吗";
p1 = c; //用char* 类型的字符串赋值给p1
string b = "袁绍";
p1 = b; //用string类型数组初始化p1;
char c = 'd';
p1 = c; //用字符初始化
///
string p2;
char *c = "helloworld";
p2.assign(c);
p2.assign(c, 5);
p2.assign(2, 'c');
string p3("good morning");
p2.assign(p3, 3, 5); //把p3从第3个字符开始之后的5个字符,赋值给p2
}
int main()
{
test();
return 0;
}
string存取字符串:
#include<iostream>
#include<stdexcept>
using namespace std;
//string 存取字符操作
//char& operator[](int n) 通过[]存取字符串里面的数据
//char& at(int n) 通过函数存取字符串里面的数据
void test()
{
string p("helloworld");
for (int i = 0; i <p.size() ; ++i)
{
cout << p[i] << endl;
}
}
void test2()
{
string p("helloworld");
for (int i = 0; i < p.size(); ++i)
{
cout << p.at(i);
}
}
//[]和at存取数据到底有没有什么区别呢?有的
//区别就是[]不会抛出异常而是直接挂掉,at会抛出异常等待处理
//void test3()
//{
// string p = "helloworld";
// try
// {
// cout << p[100] << endl;
// }
// catch (out_of_range&e)
// {
// cout << e.what() << endl;
// }
//
//}
void test4()
{
string p = "helloworld";
try
{
cout << p.at(100) << endl;
}
catch (out_of_range&e)
{
cout << e.what() << endl;
}
}
int main()
{
test();
test2();
test4();
return 0;
}
string拼接操作:
#include<iostream>
#include<string>
using namespace std;
void test1()
{
string p1 = "老鼠";
string p2 = "爱大米";
p1 += p2;
cout << p1 << endl;
/
char* p3 = "老鼠";
char* p4 = "爱大米";
string p; //最后必须用string类型的变量进行接收
p += p3;
p += p4;
cout << p << endl;
//
string pp;
char a = 'a';
char b = 'b';
pp += a;
pp += b;
cout << pp << endl;
}
int main()
{
test1();
return 0;
}
#include<iostream>
#include<string>
using namespace std;
void test1()
{
string p("请叫我");
char* p1("女王大人");
p.append(p1);
cout << p << endl;
//
string pp("请叫我");
char* pp1("女王大人");
pp.append(pp1, 4); //将前四个字符连接到pp上
cout << pp << endl;
}
//太多了不写了不写了?
int main()
{
test1();
return 0;
}
string查找操作:
#include<iostream>
#include<string>
using namespace std;
void test1()
{
string p("abcdef");
//string& find(const string& str,int pos = 0) pos默认参数,可以不给不给的话就从第0号元素去找,成功就返回找到的第一个元素的下标,没找到就返回-1
int pos = p.find("bc");
cout << pos << endl;
int post2 = p.rfind("bc"); //r.find()是从右到左进行查找 ,给返回的是最后一个元素出现的位置
cout << post2 << endl;
}
int main()
{
test1();
return 0;
}
#include<iostream>
#include<string>
using namespace std;
void test2()
{
//string& replace(int pos,int n,const string&str) 用str字符串替换从pos开始的n个字符
string p("hello");
p.replace(1, 3, "woc");
cout << p << endl;
}
int main()
{
test2();
return 0;
}
string比较操作:
#include<iostream>
#include<string>
using namespace std;
//compare比较的时候> 返回1 ,<返回-1,=返回0
void test2()
{
string p1("ab");
string p2("abc");
if (p1.compare(p2) == 0)
{
cout << "相等" << endl;
}
else if (p1.compare(p2) > 0)
{
cout << "p1 > p2" << endl;
}
else if (p1.compare(p2) < 0)
{
cout << "p1 < p2" << endl;
}
}
int main()
{
test2();
return 0;
}
string子串:
#include<iostream>
#include<string>
using namespace std;
//string子串 string substr(int pos = 0,int n =npos)const 返回由pos开始的n个字符组成的字符串
void test2()
{
string p1("abcdef");
string p2 = p1.substr(1, 3); //从第一个字符开始跨过后面的3个字符,返回剩下的字符
cout << p2 << endl; //bcd
//
string p3("http//:2416390994@qq.com");
int pos = p3.find('@');
int post = p3.find(':');
string p4 = p3.substr(post + 1,pos-post-1); //输出从:开始后面pos-post-1(数字长度)长度的字符
cout << p4 << endl;
}
int main()
{
test2();
return 0;
}
string的插入和删除操作:
#include<iostream>
#include<string>
using namespace std;
void test2()
{
string p1("hello");
p1.insert(1, "123456");
cout << p1 << endl; //结果h123456ello
p1.erase(1, 3);//从第一个开始删,删三个字符
cout << p1 << endl; //结果h456ello
}
using namespace std;
int main()
{
test2();
return 0;
}
string和c-style字符串转换:
#include<iostream>
#include<string>
using namespace std;
void func1(string s)
{
cout << s << endl;
}
void func2(const char* s)
{
cout << s << endl;
}
void test2()
{
string p("abc");
const char* s = p.c_str(); //.c_str()之后类型为const char*
cout << s << endl;
string p1(s); //这一步转换直接用的是string类内部的构造函数
cout << p1 << endl;
//
//隐式类型转换
string s2(p1);
char* name("abcd");
func1(name); //void func1(string s),进行了隐式类型转换,char* 可以转为string
//func2(s2); 但是 void func2(const char* s) 无法转变成char*
}
int main()
{
test2();
return 0;
}
将一段字符全变成大写或者小写:
#include<iostream>
#include<string>
using namespace std;
void test2()
{
string p("abcDEfGh");
for (int i = 0; i < p.size(); ++i)
{
p[i] = toupper(p[i]); //变成大写
}
cout << p << endl;
for (int i = 0; i < p.size(); ++i)
{
p[i] = tolower(p[i]); //变成小写
}
cout << p << endl;
}
int main()
{
test2();
return 0;
}
成员变量和静态变量的区别
1、两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象被回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2、调用方式不同
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3、别名不同
成员变量也称为实例变量。
静态变量也称为类变量。
4、数据存储位置不同
成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据
#include<iostream>
using namespace std;
class person
{
public:
static int man;
};
int person::man = 10;
int main()
{
cout << person::man << endl;
return 0;
}