写在前面:
C\C++基础,两篇文章,是本人学习C\C++的学习笔记。比较实用,没有太多理论上的描述,需要仔细看的是一些代码的注释。C\C++是JNI的基础,这两篇学习笔记看完之后,应该能对C\C++有一个初步的了解,为后续学习JNI打下一些基础。
一、 C++初级
1.C++版 HelloWorld
#include <iostream>
using namespace std;
int main()
{
std::cout << "Hello, World!" << std::endl;
cout << "C++" << endl; // 上面引入了命名空间,这里就可以省略std:: // endl 换行的意思
cout << "" << endl;
cout << "\n" << "\n" << "\n";
return 0;
}
2.引用
3.深拷贝和浅拷贝
4.this关键字
#include <iostream>
using namespace std;
class Student{
private:
char * name;
int age;
public:
void setName(char * name){
this->name = name;
}
void setAge(int age){
this->age = age;
}
char * getName(){
return this->name;
}
int getAge(){
return this->age;
}
// 声明一个静态变量
static int id; // 先声明
// 这里还有一个默认的构造函数 会在栈区开辟空间 暴露 this 指针
};
// 再实现
int Student::id = 9527;
int main(){
Student student;
student.setAge(99);
cout << student.getAge() << endl;
Student student1;
student1.setAge(88);
student1.id = 990;
cout << student1.getAge() << endl;
Student student2;
student2.setAge(77);
student2.id = 880;
cout << student2.getAge() << endl;
return 0;
}
由上述代码引发的思考:为什么设置age可以准确的设置到student和student1、student2中?
每new出一个student,就会在栈区开辟出一块空间,每个student 会有一个默认的构造函数,暴露this指针。this指针会指向代码区,这个区域存放getAge的函数主体,每个Student的this指针都指向代码区域的副本。 静态区没有this的概念,只有一块区域,每次更改值都会改变静态区的id。如下图所示:
const修饰函数的this意义何在
#include <iostream>
using namespace std;
//类型 * const 指针常量 地址所对应的值能改,但是地址不能改
// const 类型 * 常量指针 不允许修改指针地址所对应的值,可以去修改地址
// const 类型 * const 常量指针常量 什么都不能改 地址不能改 地址对应的值也不能改
class Worker{
public:
char * name;
int age = NULL; // C++中,没有默认值,如果不给默认值,默认值是系统值 -64664
void change1(){
// 为什么可以修改age?
// 这个函数里默认持有了隐式的this指针 并且会这样修饰 Worker * const this
// 类型 * const 指针常量 : 代表指针地址不能被修改,但是指针地址的值是可以修改的
// this = 0x6546; // 指针常量的值不能被修改,编译不通过
// 但是指针地址指向的值是可以修改的
this->age = 100;
}
void change2() const{
// 现在 this等价于const Worker * const 常量指针常量
// 常量指针常量: 什么都不能改 地址不能改 地址对应的值也不能改
}
};
6.友元函数
一般函数无法访问类中的私有成员,但是友元函数是类的好朋友,可以访问类中的私有成员
#include <iostream>
using namespace std;
class Person{
private: // 私有的age,外界不能访问
int age = 0;
public:
Person(int age) {
this->age = age;
}
int getAge() {
return this->age;
}
// 定义友元函数 (声明,没有实现)
friend void updateAge(Person * person, int age);
}
// 友元函数的实现,可以访问所以私有成员
void updateAge(Person* person, int age) {
// 默认情况下:不能修改 私有的age
// 谁有这个权限:友元(拿到所有私有成员)
person->age = age;
}
int main() {
Person person = Person(9);
updateAge(&person, 88); // 调用updateAge
cout << person.getAge() << endl;
return 0;
}
6.静态函数,友元函数,普通函数,构造函数,析构函数,拷贝构造函数,有啥区别?
pig.h
#include <iostream>
using namespace std;
// JNI 为什么一定要用这个东西(后面专门)
#ifndef PIG_H // 你有没有这个宏(Java 宏==常量)
#define PIG_H // 定义这个宏
class Pig {
private:
int age;
char * name;
public:
// 静态成员声明
static int id;
// 构造函数的声明系列
Pig();
Pig(char *);
Pig(char *,int);
// 析构函数
~Pig();
// 拷贝构造函数
Pig(const Pig & pig);
// 普通函数 set get
int getAge();
char * getName();
void setAge(int);
void setName(char *);
void showPigInfo() const; // 常量指针常量 只读
// 静态函数的声明
static void changeTag(int age);
// 不要这样干
// void changeTag(int age);
// 友元函数的声明
friend void changeAge(Pig * pig, int age);
};
#endif // 关闭/结尾
pig.cpp : 对头文件中定义的方法的实现
#include "Pig.h"
// TODO ====================== 下面是 普普通通 常规操作 对象::
// 实现构造函数
Pig::Pig() {
cout << "默认构造函数" << endl;
}
Pig::Pig(char * name) {
cout << "1个参数构造函数" << endl;
}
Pig::Pig(char * name, int age) {
cout << "2个参数构造函数" << endl;
}
// 实现析构函数
Pig::~Pig() {
cout << "析构函数" << endl;
}
// 实现 拷贝构造函数
Pig::Pig(const Pig &pig) {
cout << "拷贝构造函数" << endl;
}
int Pig::getAge() {
return this->age;
}
char * Pig::getName() {
return this->name;
}
void Pig::setAge(int age) {
this->age = age;
}
void Pig::setName(char * name) {
this->name = name;
}
void Pig::showPigInfo() const {
} // 常量指针常量 只读
// TODO =============================== 静态 和 友元 注意点 自己理解
// 实现 静态属性【不需要增加 static关键字】
int Pig::id = 878;
// 实现静态函数,【不需要增加 static关键字】
void Pig::changeTag(int age) {
}
// 友元的实现
// 友元特殊:不需要关键字,也不需要 对象:: ,只需要保证 函数名(参数)
void changeAge(Pig * pig, int age) {
}
关于友元类的思考与延伸:
Java中可以使用反射,获取到类中的私有属性。使用C++代码实现的话,可以直接使用友元类,获取累中的私有属性。 代码如下:
// ImageView 私有成员 可以通过Class来访问,但是Class操作的native C++代码
// ImageView 私有成员 你能访问它的私有成员吗 Class
#include <iostream>
using namespace std;
class ImageView {
private:
int viewSize;
friend class Class; // 声明友元类
};
// 实现友元类 Java每个类,都会有一个Class,此Class可以操作 ImageView私有成员
class Class {
public:
ImageView imageView;
void changeViewSize(int size) {
imageView.viewSize = size;
}
int getViewSize() {
return imageView.viewSize;
}
};
int main() {
Class mImageViewClass;
mImageViewClass.changeViewSize(600);
cout << mImageViewClass.getViewSize() << endl;
return 0;
}
7.C++ 操作符重载
7.1 类外操作符重载
#include <iostream>
using namespace std;
// 类外运算符重载
class Point{
private:
int x,y;
public:
Point(int x, int y) : x(x),y(y) {}
void setX(int x){
this->x = x;
}
void setY(int y){
this->y = y;
}
int getX(){
return this->x;
}
int getY(){
return this->y;
}
};
// 类外运算符重载 外部是不能获取到内部私有成员的
Point operator + (Point point1, Point point2){
int x = point1.getX() + point2.getX();
int y = point1.getY() + point2.getY();
Point p(x,y);
return p;
}
int main() {
Point p1(1000,2000);
Point p2(3000,4000);
Point p = p1 + p2;
cout << p.getX() <<" , "<< p.getY() << endl;
return 0;
}
7.2 类里运算符重载
// 类里操作符重载 + - i++ ++i << 连续打印
#include <iostream>
using namespace std;
class Point{
private:
int x,y;
public:
Point(int x,int y):x(x),y(y){}
void setX(int x){
this->x = x;
}
void setY(int y){
this->y = y;
}
int getX(){
return this->x;
}
int getY(){
return this->y;
}
// 类里操作符重载 第一种情况: 未使用const 关键字
Point operator + (Point p){
// this 指针指向当前对象
int x = this->x + p.getX();
int y = this->y + p.getY();
return Point(x,y);
}
// 类里操作符重载 第二种情况: 使用const 关键字
// const 关键字 只读 &性能的提高 如果增加了 & 引用,就是给这块内存空间取一个别名
Point operator + (const Point &point){
int x = this->x + point.x;
int y = this->y + point.y;
return Point(x,y);
}
Point operator - (const Point &point){
int x = this->x - point.x;
int y = this->y - point.y;
return Point(x,y);
}
// ++对象
void operator ++ (){
this->x = this->x + 1;
this->y = this->y + 1;
}
// 对象++
void operator ++(int){
this->x = this->x + 1;
this->y = this->y +1;
}
// 输出运算符重载
friend void operator << (ostream & _START,Point point){
_START << "Point 输出 : x = " << point.x << "y = " << point.y << endl;
}
// 多重输出 返回ostream
friend ostream & operator >> (ostream & _START,const Point &point){
_START << "开始输出: x = " << point.x << " y = " << point.y << endl;
return _START;
}
// 输入运算符重载 接收用户的输入 把输入的信息 给x y
friend istream & operator >> (istream & _START, Point & point){
_START >> point.x >> point.y;
return _START;
}
};
int main(){
Point p1(1000,2000);
Point p2(3000,4000);
Point point = p2 + p1;
cout << "+ x = " << point.getX() << ". y = " << point.getY() << endl;
Point point1 = p2 - p1;
cout << "- x = " << point1.getX() << ". y = " << point1.getY() << endl;
Point point2(1000,2000);
point2++;
cout << point2.getX() << " --- " << point2.getY() << endl;
++point2;
cout << point2.getX() << " --- " << point2.getY() << endl;
// 输出
cout << point2 ;
// 换行
cout << endl;
cout >> point >> point1 >> point2 ;
// cin输入
Point point3(5000,6000);
cin >> point3;
cout << "你输入的是:" << point3.getX() << endl;
cout << "你输入的是:" << point3.getY() << endl;
return 0;
}
7.3 括号运算符
#include <iostream>
using namespace std;
// 写一个小容器 模拟容器
class ArrayClass{
private:
// C++ 默认都是系统值
int size = 0; // 如果不赋值, size就是系统值 -13275 会出现后患无穷的问题
int * arrayValue; // 数组存放int类型的很多值
public:
void set(int index,int value){
arrayValue[index] = value; // 这个[] 是系统的
size += 1;
}
int getSize(){
return this->size;
}
int operator[](int index){
return arrayValue[index]; // 这个[] 是系统的
}
};
void printArrayClass(ArrayClass aClass){
cout << aClass.getSize() << endl;
for(int i = 0; i < aClass.getSize();++i) {
cout << aClass[i] << endl; // [] 是我们自己的符号重载
}
}
int main(){
ArrayClass arrayClass;
arrayClass.set(0,1000);
arrayClass.set(1,2000);
arrayClass.set(2,3000);
arrayClass.set(3,4000);
arrayClass.set(4,5000);
printArrayClass(arrayClass);
return 0;
}
8. C++继承中的继承
8.1 单继承
// C++对象继承
#include <iostream>
using namespace std;
class Person{
public:
char * name;
int age;
public:
Person(char * name,int age):name(name){
this->age=age;
cout << "Person 构造函数" << endl;
}
void print(){
cout << this->name << "," << this->age << endl;
}
};
// 继承
/*
* 1. 默认是私有继承: 隐式代码 : private Person
* 2. 私有继承: 在子类里面是可以访问父类的成员,但在类外不行
* 3. 必须公开继承,才可以访问父类的成员
*/
class Student : public Person{
private:
char * course;
public:
Student(char * name,int age,char * course): Person(name,age),course(course){
cout << "student 构造函数" << endl;
}
void test(){
cout << name << endl;
cout << age << endl;
cout << course << endl;
print();
}
};
int main() {
Student student("xx", 90, "Play");
student.name = "YY";
student.test();
return 0;
}
8.2 多继承
C++的多继承,会导致二义性
// C++的多继承 导致二义性
#include <iostream>
using namespace std;
class BaseActivity1{
public:
void onCreate(){
cout << "BaseActivity1 OnCreate()" << endl;
}
void onStart(){
cout << "BaseActivity1 onStart()" << endl;
}
void show(){
cout << "BaseActivity1 show()" << endl;
}
};
class BaseActivity2{
public:
void onCreate(){
cout << "BaseActivity2 OnCreate()" << endl;
}
void onStart(){
cout << "BaseActivity2 onStart()" << endl;
}
void show(){
cout << "BaseActivity2 show()" << endl;
}
};
class BaseActivity3{
public:
void onCreate(){
cout << "BaseActivity3 OnCreate()" << endl;
}
void onStart(){
cout << "BaseActivity3 onStart()" << endl;
}
void show(){
cout << "BaseActivity3 show()" << endl;
}
};
// 子类 继承 三个父类
class MainActivity1 : public BaseActivity1,public BaseActivity2,public BaseActivity3{
public:
void onCreate() {
cout << "MainActivity1 onCreate" << endl;
}
void onStart() {
cout << "MainActivity1 onStart" << endl;
}
void showSonInfo() {
cout << "MainActivity1 showSonInfo" << endl;
}
void show(){
cout << "MainActivity1 show" << endl;
}
};
int main(){
MainActivity1 mainActivity1;
mainActivity1.onCreate();
mainActivity1.onStart();
mainActivity1.showSonInfo();
// 这里会导致二义性 不知道去哪个父类里面去找show方法
// mainActivity1.show();
// 解决方式1 : 明确指定父类
mainActivity1.BaseActivity1::show();
mainActivity1.BaseActivity2::show();
mainActivity1.BaseActivity3::show();
//解决方案二:子类上 重写父类的show()
mainActivity1.show();
return 0;
}
二义性的解决方案:
// 二义性
#include <iostream>
using namespace std;
class Object{
public:
int number;
};
class BaseActivity1 : public Object{
};
class BaseActivity2 : public Object{
};
class Son : public BaseActivity1,public BaseActivity2{
public:
int number;
};
int main(){
Son son;
// 第一种解决二义性的方案:明确指定
son.BaseActivity1 :: number = 1000;
son.BaseActivity2 :: number = 1000;
// 第二种解决方法:在类中定义同名成员 覆盖掉父类的相关成员
son.number = 2000;
// 第三种解决方案 【虚基类】 属于 虚继承的范畴
return 0;
}
// 二义性
#include <iostream>
using namespace std;
class Object{
public:
int number;
};
class BaseActivity1 : public Object{
};
class BaseActivity2 : public Object{
};
class Son : public BaseActivity1,public BaseActivity2{
public:
int number;
};
int main(){
Son son;
// 第一种解决二义性的方案:明确指定
son.BaseActivity1 :: number = 1000;
son.BaseActivity2 :: number = 1000;
// 第二种解决方法:在类中定义同名成员 覆盖掉父类的相关成员
son.number = 2000;
// 第三种解决方案 【虚基类】 属于 虚继承的范畴
return 0;
}
8.3 虚基类
// 虚基类 属于虚继承的范畴 虚基类 另外制造了一份 变量和方法 让子类去继承
#include <iostream>
using namespace std;
class Object{
public:
int number;
void show(){
cout << "Object show run..." << endl;
}
};
// 父类1
class BaseActivity1 :virtual public Object{
//public:
// int number;
};
// 父类2
class BaseActivity2 : virtual public Object{
//public:
// int number;
};
// 子类
class Son : public BaseActivity1,public BaseActivity2{
};
int main(){
Object object;
BaseActivity1 baseActivity1;
BaseActivity2 baseActivity2;
Son son;
object.number = 100;
baseActivity1.number = 200;
baseActivity2.number = 300;
son.number = 400;
object.show();
baseActivity1.show();
baseActivity2.show();
son.show();
cout << object.number << endl;
cout << baseActivity1.number << endl;
cout << baseActivity2.number << endl;
cout << son.number << endl;
return 0;
}
8.4 源码中属性初始化方法
#include <iostream>
using namespace std;
class Person{
protected:
string name;
int age;
public :
Person(string name,int age) : name(name),age(age){}
};
class Course{
private:
string name;
public:
Course(string name) : name(name){}
};
class Student : public Person{
private:
Course course; // 对象成员
public:
Student(string name,int age,Course course1,string courseName) : Person(name,age),course(courseName){
}
};
int main(){
Course course("C++");
Student student("Name",35,course,"CourseName");
return 0;
}
8.5 虚继承
#include <iostream>
using namespace std;
// 祖父类
class Object{
public:
string info;
};
// 父类
class Base1 : virtual public Object{};
class Base2 : virtual public Object{};
// 子类
class Main1 : public Base1,public Base2{};
int main(){
Object object;
Base1 base1;
Base2 base2;
Main1 main1;
object.info = "A";
base1.info = "B";
base2.info = "C";
main1.info = "D";
cout << object.info << endl;
cout << base1.info << endl;
cout << base2.info << endl;
cout << main1.info << endl;
exit(0);
}
原理图:
9.静态多态
编译期已经决定,调用哪个函数了 : 重载
#include <iostream>
using namespace std;
void add(int number1, int number2) {
cout << number1 + number2 << endl;
}
void add(float number1, float number2) {
cout << number1 + number2 << endl;
}
void add(double number1, double number2) {
cout << number1 + number2 << endl;
}
int main() {
add(10000, 10000);
add(1.9f, 2.8f);
add(545.4, 654.54);
return 0;
}
10.纯虚函数
C++的纯虚函数 就相当于Java的抽象类
// 纯虚函数 C++的纯虚函数 就相当于Java的抽象类
#include <iostream>
using namespace std;
class BaseActivity1{
private:
void setContentView(string layoutId){
cout << layoutId << endl;
}
public:
void onCreate(){
setContentView(getLayoutID());
initView();
initData();
initListener();
}
// 纯虚函数是必须继承的 (如果子类没有重写纯虚函数,子类就是抽象类)虚函数是不是不必须的
// 纯虚函数
// virtual string getLayoutID() ; // 没有赋值的 是虚函数
virtual string getLayoutID() = 0; // 赋值的是纯虚函数
virtual void initView() = 0;
virtual void initListener() = 0;
virtual void initData() = 0;
};
class MainActivity : public BaseActivity1{
string getLayoutID(){
return " MainActivity ";
}
void initView(){}
void initListener(){}
void initData(){}
};
class HomeActivity : public BaseActivity1{
string getLayoutID(){
return " HomeActivity ";
}
void initView(){
}
void initListener(){
}
void initData(){
}
};
class LoginActivity : public BaseActivity1{
string getLayoutID(){
return " LoginActivity ";
}
void initView(){
}
void initListener(){
}
void initData(){
}
};
int main(){
MainActivity mainActivity;
return 0;
}
11.全纯虚函数
相当于Java的接口
// 全纯虚函数 (相当于Java中的接口)
#include <iostream>
using namespace std;
class Student{
int _id;
string name;
int age;
};
// 此类所有的函数, 都是纯虚函数 相当于Java的接口
class IStudent_DB{
virtual void insertStudent(Student student) = 0;
virtual void deleteStudent(int _id) = 0;
virtual void updateStudent(int _id,Student student) = 0;
virtual void queryByStudent(Student student) = 0;
};
class IStudent_Impl : IStudent_DB{
public:
void insertStudent(Student student){
}
void deleteStudent(int _id){
}
void updateStudent(int _id,Student student){
}
void queryByStudent(Student student){
}
};
class IStudent_Impl2 : IStudent_DB{
public:
void insertStudent(Student student){
}
void deleteStudent(int _id){
}
void updateStudent(int _id,Student student){
}
void queryByStudent(Student student){
}
};
class IStudent_Impl3 : IStudent_DB{
public:
void insertStudent(Student student){
}
void deleteStudent(int _id){
}
void updateStudent(int _id,Student student){
}
void queryByStudent(Student student){
}
};
int main(){
IStudent_Impl iStudent1;
IStudent_Impl2 iStudentImpl2;
IStudent_Impl3 iStudentImpl3;
cout << "Success" << endl;
return 0;
}
12.回调
// 回调
#include <iostream>
using namespace std;
class SuccessBean{
public:
string userName;
string userPwd;
SuccessBean(string username,string userpwd) : userName(username),userPwd(userpwd){
}
};
class ILoginResponse{
public:
virtual void loginSuccess(int code,string message,SuccessBean successBean) = 0;
virtual void loginError(int code,string message) = 0;
};
void loginAction(string name,string pwd,ILoginResponse & loginResponse){
if(name.empty() || pwd.empty()){
cout << "用户名或密码为空" << endl;
return;
}
if("Kim" == name && "123" == pwd){
loginResponse.loginSuccess(200,"登录成功", SuccessBean(name,"恭喜进入"));
}else{
loginResponse.loginError(400,"登录失败");
}
}
class ILoginResponseImpl : public ILoginResponse{
public:
void loginSuccess(int code,string msg,SuccessBean successBean){
cout << "恭喜登录成功!"
<< ",code : "
<< code
<< ",msg : "
<< msg
<< ",successBean : "
<< successBean.userName
<< ","
<< successBean.userPwd
<< endl;
}
void loginError(int code,string msg){
cout << "登录失败," << "code : " << code << ",message : " << msg << endl;
}
};
int main(){
string username;
cout << "请输入用户名 : " <<endl;
cin >> username;
string pwd;
cout << "请输入密码:" << endl;
cin >> pwd;
ILoginResponseImpl iLoginResponse;
loginAction(username,pwd,iLoginResponse);
return 0;
}
12.模板函数
相当于Java的泛型
// 模板函数 相当于Java的泛型
#include <iostream>
using namespace std;
//void add(int number1,int number2){
// cout << number1 + number2 << endl;
//}
//
//void add(float number1,float number2){
// cout << number1 + number2 << endl;
//}
//
//void add(double number1,double number2){
// cout << number1 + number2 << endl;
//}
// 模板函数 == Java泛型
template <typename TT>
void add(TT n1,TT n2){
cout << "模板函数:" << n1 + n2 <<endl;
}
int main(){
add(290,10);
add(2.0f,3.0f);
add(2.13,3.45);
add<string>("AAA","BBB");
return 0;
}
13.继承关系的时候,构造函数和析构函数的顺序问题
// 构造函数和析构函数的顺序问题
#include <iostream>
using namespace std;
class Person{
public:
string name;
Person(string name) : name(name) {
cout << "Person 构造函数" << endl;
}
~Person(){
cout << "Person 析构函数" << endl;
}
virtual void test(){
cout << "父 test..." << endl;
}
};
class Student : public Person{
public:
string name;
Student(string name) : Person(name){
cout << "Student 构造函数" << endl;
}
~Student(){
cout << "Student 析构函数" << endl;
}
void test(){
cout << "子 test..." << endl;
}
};
int main(){
Student student("Kim");
student.test();
return 0;
}
打印结果:
Person 构造函数
Student 构造函数
子 test...
Student 析构函数
Person 析构函数
14. C++ 容器
14.1 Vector
Vector内部是封装了动态大小数组作为容器,能够存放任意的动态数组。
/**
* STL C++的标准模板库
* STL Standard Template Library
* C++ 的 vector 向量 容器 (内部 : 封装动态大小数组作为容器,能够存放任意的动态数组)
*/
#include <iostream>
#include <vector> // 引入vector 容器支持
using namespace std;
int main(){
vector<int> vector1;
vector<int> vector2(10); // 指定10个空间大小
vector<int> vector3(10,0); // 有了10个值,每个值都是0
vector<int> vector4;
// 插入数据 每次都插入到第一个
vector4.insert(vector4.begin(),40);
vector4.insert(vector4.begin(),80);
vector4.insert(vector4.begin(),100);
vector4.insert(vector4.begin(),150);
vector4.insert(vector4.begin(),200);
// 第一个
cout << " 修改前:vector4.front():" << vector4.front() << endl;
vector4.front() = 99; // 默认修改第一个
cout << " 修改后:vector4.front():" << vector4.front() << endl;
// 最后一个
cout << "修改前 :vector4.back() " << vector4.back() << endl;
vector4.back() = 88;
cout << "修改后:vector4.back() " << vector4.back() << endl;
vector4.erase(vector4.begin()); // 移除第一个元素
// 循环打印 默认是从大到小输出
for(int i = 0; i < vector4.size(); i++){
cout << "item : " << vector4[i] << endl;
}
// 迭代器 循环遍历
// for(vector<int>::iterator iteratorVar = vector4.begin() ; iteratorVar != vector4.end(); iteratorVar ++){
// cout << "迭代器:" << *iteratorVar << endl;
// }
for(auto iteratorVar = vector4.begin(); iteratorVar != vector4.end(); iteratorVar ++){
cout << "迭代器:" << *iteratorVar << endl;
}
return 0;
}
14.2 Stack 栈
先进后出,后进先出,手枪子弹上膛的一个思路。
// stack 栈 后进先出 先进后出
#include <iostream>
#include <stack>
using namespace std;
int main(){
stack<int> stackVar;
// 压栈 stack无法指定位置去压栈
stackVar.push(30);
stackVar.push(60);
stackVar.push(90);
// 循环遍历stack 是行不通的 因为stack内部没有重载[]运算符
// stack中也没有迭代器
// 所以要循环stack 就需要把元素都弹栈 这种方式是可以的 但是没必要 全部元素都弹完了
while (!stackVar.empty()){
// 获得栈顶元素
int top = stackVar.top();
cout << "获取栈顶元素 :" << top << endl;
stackVar.pop(); // 把栈顶元素弹出去
}
return 0;
}
14.3 queue 队列
// queue 队列使用 内部: 链表 数组 先进先出
#include <iostream>
#include <queue>
using namespace std;
int main(){
queue<int> queueVar;
queueVar.push(20);
queueVar.push(40);
queueVar.push(60);
// FIFO 原则 第一个元素就是20
cout << "修改前:queueVar.front() " << queueVar.front() << endl;
queueVar.front() = 88;
cout << "修改后:queueVar.front() " << queueVar.front() << endl;
// 最后一个 最后一个元素是60
cout << "修改前:queueVar.back() " << queueVar.back() << endl;
queueVar.back() = 99;
cout << "修改后:queueVar.back() " << queueVar.back() << endl;
while (!queueVar.empty()){
cout << " 第一次遍历 : " << queueVar.front() << endl;
queueVar.pop(); // 把前面的元素给消费掉
}
while (!queueVar.empty()){
// 没有元素了
cout << " 第二次遍历 : " << queueVar.front() << endl;
queueVar.pop(); // 把前面的元素给消费掉
}
return 0;
}
14.4 优先级队列 : priority_queue
增加了从大到小或者从小到大排序
// 优先级队列
#include <iostream>
#include <queue>
using namespace std;
int main(){
// 优先级队列 默认做了从大到小排序
/**
* 对于priorityQueue来说, C++其实默认的隐式代码是:
* priority_queue<int, vector<int>, less<int>> priorityQueue;
* less ==》源码中: less<int> return _x < _y 上一个元素和当前元素比较 返回true 或者 false 从大到小排序
*
* greater ==> 源码中: return _x > _y 从小到大排序
*
*/
// 从大到小排序
// priority_queue<int> priorityQueue;
// priority_queue<int, vector<int>, less<int>> priorityQueue;
// 从小到大排序
priority_queue<int,vector<int>,greater<int>> priorityQueue;
priorityQueue.push(10);
priorityQueue.push(50);
priorityQueue.push(70);
priorityQueue.push(20);
priorityQueue.push(40);
priorityQueue.push(30);
while (!priorityQueue.empty()){
cout << "while : " << priorityQueue.top() << endl;
priorityQueue.pop();
}
return 0;
}
14.5 List
List的内部是一个链表结构
// List 内部 采用链表
#include <iostream>
#include <list>
using namespace std;
int main(){
list<int> listVar;
// 插入数据
listVar.push_front(50);
listVar.push_back(100);
listVar.insert(listVar.begin(),70);
listVar.insert(listVar.end(),80);
// 修改操作
listVar.front() = 85;
listVar.back() = 95;
// 删除操作
listVar.erase(listVar.begin());
listVar.erase(listVar.end());
for(list<int> :: iterator it = listVar.begin() ; it != listVar.end(); it++){
cout << *it <<endl;
}
return 0;
}
14.6 Set容器
Set容器内部是一个红黑树结构 会对存入的数据排序,但是绝对不允许相同
// set容器 内部: 红黑树结构 会对存入的数据排序,但是绝对不允许相同
#include <iostream>
#include <set>
using namespace std;
int main(){
// 默认情况下 从小到大
set<int,less<int>> setVar;
// 添加参数 不需要用迭代器 也不需要指定位置
setVar.insert(1);
setVar.insert(3);
setVar.insert(2);
setVar.insert(4);
pair<set<int,less<int>>::iterator ,bool> res = setVar.insert(8);
bool insert_success = res.second;
if(insert_success){
cout << "插入成功!" << endl;
for(;res.first != setVar.end() ; res.first ++){
cout << *res.first << endl;
}
}else{
cout << "插入失败!" << endl;
}
// 遍历
for(auto it = setVar.begin(); it != setVar.end(); it ++){
cout << *it << endl;
}
return 0;
}
14.7 谓词
// 谓词 设计对象的排序
#include <iostream>
#include <set>
using namespace std;
class Person{
public:
string name;
int id;
Person(string name,int id) : name(name),id(id){}
};
struct compareAction2{
public:
bool operator()(const Person &_x,Person &_y){
return _x.id < _y.id;
}
};
int main(){
// 在这里使用自定义的谓词
set<Person,compareAction2> setVar;
Person p1("A",1);
Person p2("B",2);
Person p3("C",3);
setVar.insert(p1);
setVar.insert(p2);
setVar.insert(p3);
for(set<Person> :: iterator it = setVar.begin();it != setVar.end(); it++){
cout << it->name.c_str() << endl;
}
return 0;
}
14.8 Map
Map会对key进行排序,并且key不能重复
// Map的学习 : Map会对key进行排序,并且key不能重复
#include <iostream>
#include <map>
using namespace std;
int main(){
map<int,string> mapVar;
// 插入数据 三种方式
// 第一种方式:
mapVar.insert(pair<int,string>(1,"一"));
// 第二种方式
mapVar.insert(make_pair(2,"二"));
// 第三种方式
mapVar.insert(map<int,string>::value_type(3,"三"));
// 第四种方式 覆盖修改时使用
mapVar[4] = "4";
mapVar[4] = "肆";
// 循环打印 迭代器
for(map<int,string>::iterator it = mapVar.begin();it != mapVar.end(); it++){
cout << it->first << " , " << it->second.c_str() << endl;
}
// 怎么判断插入成功了没 insert 的返回值 :std::pair<iterator, bool>
std::pair<map<int,string>::iterator , bool> pair = mapVar.insert(map<int,string>::value_type(4,"六"));
if(pair.second){
cout << "插入成功!" << endl;
}else{
cout << "插入失败!" << endl;
}
// 插入后的数据
for(pair.first == mapVar.begin();pair.first != mapVar.end();pair.first ++){
cout << pair.first->first << " , " << pair.first->second << endl;
}
// find的返回值 : iterator
map<int,string>:: iterator findResult = mapVar.find(3);
if(findResult != mapVar.end()){
cout << "找到了" << findResult->first << " , " << findResult->second.c_str() << endl;
}else{
cout << "没找到 " << endl;
}
return 0;
}
14.9 multimap容器
multimap容器:1.key可以重复, 2.key重复的数据可以分组, 3.key会排序, 4.value不会排序
//multimap : 1.key可以重复, 2.key重复的数据可以分组, 3.key会排序, 4.value不会排序
#include <iostream>
#include <map>
using namespace std;
int main(){
multimap<int,string> multimapVar;
multimapVar.insert(make_pair(10,"一"));
multimapVar.insert(make_pair(10,"二"));
multimapVar.insert(make_pair(10,"三"));
multimapVar.insert(make_pair(10,"四"));
multimapVar.insert(make_pair(10,"五"));
multimapVar.insert(make_pair(30,"六"));
multimapVar.insert(make_pair(30,"七"));
multimapVar.insert(make_pair(30,"八"));
multimapVar.insert(make_pair(30,"九"));
multimapVar.insert(make_pair(30,"十"));
multimapVar.insert(make_pair(20,"六"));
multimapVar.insert(make_pair(20,"七"));
multimapVar.insert(make_pair(20,"八"));
multimapVar.insert(make_pair(20,"九"));
multimapVar.insert(make_pair(20,"十"));
for(auto it = multimapVar.begin() ; it != multimapVar.end() ; it ++){
cout << it->first << " , " << it->second << endl;
}
cout << endl;
// 输入查询
int result;
cout << "请输入你要查询的key,为int类型" << endl;
cin >> result;
multimap<int,string>::iterator iterator = multimapVar.find(result);
while (iterator != multimapVar.end()){
cout << iterator->first << "," << iterator->second << endl;
//
iterator++;
if(iterator->first != result){
break; // 循环结束
}
if(iterator == multimapVar.end()){
break; // 循环结束
}
}
return 0;
}
15. 谓词一
谓词就是仿函数
// 谓词 == 仿函数
#include <iostream>
#include <algorithm>
using namespace std;
class ComPareObject{
public:
// 根据参数的个数 分为 空谓词 一元谓词 二元谓词 三元谓词
void operator()(){
cout << "仿函数" << endl;
}
};
void fun(){
cout << "普通函数" << endl;
}
int main(){
ComPareObject fun1;
fun1(); // 使用仿函数 非常像函数的调用
fun(); // 普通函数的调用
return 0;
}
16. 谓词二
#include <iostream>
#include <set>
#include <algorithm> // 算法包
using namespace std;
class showActionObj{
public:
void operator()(int content){
cout << "自定义仿函数" << content << endl;
}
};
// 普通函数
void showAction(int content){
cout << "普通函数" << content << endl;
}
int main(){
set<int> setVar;
setVar.insert(10);
setVar.insert(20);
setVar.insert(30);
setVar.insert(40);
setVar.insert(50);
/**
* for_each 方法的三个参数 :
* @param __first An input iterator. 迭代器 开始的位置
* @param __last An input iterator. 迭代器 结束的位置
* @param __f A unary function object. Function 函数 : 回调函数或者仿函数 在for_each的源码中,会把
*/
// TODO for_each 的源码:
// template<typename _InputIterator, typename _Function>
// _Function
// for_each(_InputIterator __first, _InputIterator __last, _Function __f)
// {
// // concept requirements
// __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
// __glibcxx_requires_valid_range(__first, __last);
// for (; __first != __last; ++__first)
// 在这个位置,会把_first的值传递给 __f
// __f(*__first);
// return __f; // N.B. [alg.foreach] says std::move(f) but it's redundant.
// }
for_each(setVar.begin(),setVar.end(), showActionObj());
return 0;
}
17. 谓词三
// 回调函数 和 仿函数
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
// 回调函数 也叫一元谓词
void showAction(int _first){
cout << "一元谓词" << endl;
}
// 仿函数 可扩展性更强
class showActionObj{
public:
int count;
void _count(){
cout << "第几次打印" << count << endl;
}
void operator()(int content){
cout << "仿函数" << content << endl;
count ++;
}
};
int main(){
set<int> setVar;
setVar.insert(10);
setVar.insert(20);
setVar.insert(30);
setVar.insert(40);
setVar.insert(50);
setVar.insert(60);
// 循环打印 第三个参数是一个 _Function __f
// for_each(setVar.begin(),setVar.end(), showAction);
// 这传样写 没办法打印出count 因为这个入的showActionObj是新的副本,
// 我们外面的是showActionObj的旧地址
// for_each(setVar.begin(),setVar.end(),showActionObj());
// 改进:
showActionObj s;
s = for_each(setVar.begin(),setVar.end(),s);
s._count();
return 0;
}
18.模仿源码,写仿函数
// 模仿源码 写仿函数
#include <iostream>
#include <set>
using namespace std;
// TODO less源码
//template<typename _Tp>
//struct less : public binary_function<_Tp, _Tp, bool>
//{
// _GLIBCXX14_CONSTEXPR
// bool
// operator()(const _Tp& __x, const _Tp& __y) const
// { return __x < __y; }
//};
// 根据less源码 进行仿写
class CompareObject{
public:
bool operator()(const string & _x,const string & _y) const{
return _x > _y;
}
};
int main(){
/**
* template<typename _Key, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<_Key> >
源码中,第二个参数 如果没有 就使用内置的仿函数less 可以自定义仿函数 自定义可以根据less的格式去写
*/
set<string,CompareObject> setVar; // 倒序
// set<string> setVar; // 正序
setVar.insert(setVar.begin(),"AAAAA");
setVar.insert(setVar.begin(),"BBBBB");
setVar.insert(setVar.begin(),"CCCCC");
setVar.insert(setVar.begin(),"DDDDD");
setVar.insert(setVar.begin(),"EEEEE");
setVar.insert(setVar.begin(),"FFFFF");
// 循环 打印出来是正序
for (set<string> :: iterator it = setVar.begin(); it != setVar.end() ; it++) {
cout << "循环Item : " << *it << "\t"; // 不换行
}
return 0;
}
19.对象存入容器后,对象的生命周期状态
// 对象存入容器后,对象的生命周期状态
#include <iostream>
#include <set> // set 存入对象会崩溃,因为set会自动排序,对象无法排序,所以崩溃,解决办法:自定义仿函数
#include <vector>
using namespace std;
class Person{
private:
string name;
public:
Person(string name):name(name){}
void setName(string name){
this->name = name;
}
string getName(){
return this->name;
}
// 拷贝构造函数
Person(const Person & person){
this->name = person.name; // 浅拷贝
cout << "Person的拷贝构造函数执行了...." << endl;
}
~Person(){
cout << "Person的析构函数执行了...." << endl;
}
};
int main(){
vector<Person> vectorVar;
// main函数弹栈时,析构函数执行一次
Person person("AA");
// 外面的person是旧地址,insert参数中的person是新地址 (这里调用拷贝构造函数一次)
// insert函数弹栈时,person的析构函数执行一次
vectorVar.insert(vectorVar.begin(),person);
person.setName("BB");
// main函数弹栈时,newPerson的析构函数被执行一次
Person newPerson = vectorVar.front(); // 这里得到的Person是旧地址,外面的newPerson是新地址 (这里调用拷贝构造函数一次)
cout << "newPerson : " << newPerson.getName() << endl;
return 0;
} // 执行完毕 main函数弹栈
// 拷贝构造函数 运行两次 析构函数 运行三次
20.预定义函数
// C++的预定义函数
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
// C++已经提供了 预定义函数 plus,minus,multiplies,divides,modulus ...
plus<int> add_fun;
int r = add_fun(1,2);
cout << r << endl;
plus<string> add_fun2;
string r2 = add_fun2("AAA","BBB");
cout << r2 << endl;
plus<float> add_fun3;
float r3 = add_fun3(454.45f,234.9f);
cout << r3 << endl;
return 0;
}
21. 手写预定义函数
// 手写预定义函数 根据plus源码 模仿预定义函数 plus
#include <iostream>
#include <algorithm>
using namespace std;
// plus的源码:
// template<typename _Tp>
// struct plus : public binary_function<_Tp, _Tp, _Tp>
// {
// _GLIBCXX14_CONSTEXPR
// _Tp
// operator()(const _Tp& __x, const _Tp& __y) const
// { return __x + __y; }
// };
// binary_function 源码:
template<typename _Arg1, typename _Arg2, typename _Result>
struct binary_function
{
/// @c first_argument_type is the type of the first argument
typedef _Arg1 first_argument_type;
/// @c second_argument_type is the type of the second argument
typedef _Arg2 second_argument_type;
/// @c result_type is the return type
typedef _Result result_type;
};
template<typename T>
struct plus_d /*: public binary_function<T,T,T> */{
T operator()(const T & x , const T & y){
return x + y;
}
};
int main(){
plus<int> add_fun;
add_fun(1,2);
plus_d<int> add_d;
int r = add_d(1,2);
cout << r << endl;
return 0;
}
二、C++高级之算法包
1. 函数适配器 : bind2nd bind1st
// 1. 函数适配器
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int main(){
cout << "算法包" << endl;
set<string,less<string>> setVar;
setVar.insert("AAAA");
setVar.insert("BBBB");
setVar.insert("CCCC");
for(set<string> :: iterator it = setVar.begin(); it != setVar.end(); it++){
cout << *it << endl;
}
// TODO 学习一下find_if的源码:
// template<typename _InputIterator, typename _Predicate>
// inline _InputIterator // 返回值是一个迭代器
// find_if(_InputIterator __first, // 迭代器的初始位置
// _InputIterator __last, // 迭代器的结束位置
// _Predicate __pred) // 规则
// {
// // concept requirements
// __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
// __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
// typename iterator_traits<_InputIterator>::value_type>)
// __glibcxx_requires_valid_range(__first, __last);
//
// return std::__find_if(__first, __last,
// __gnu_cxx::__ops::__pred_iter(__pred));
// }
set<string,less<string>>::iterator iterator = find_if(setVar.begin(), setVar.end(), bind1st(equal_to<string>(),"CCCC"));
if(iterator != setVar.end()){
cout << "查找到了" << endl;
}else{
cout << "没有查找到" << endl;
}
}
2. 算法包里的算法
2.1 for_each 遍历操作
// for_each 算法包里面的遍历
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class _F{
public:
void operator()(int _first){
cout << " : "<< _first << endl;
}
};
int main() {
vector<int> vectorVar;
vectorVar.insert(vectorVar.begin(),10000);
vectorVar.insert(vectorVar.begin(),20000);
vectorVar.insert(vectorVar.begin(),30000);
vectorVar.insert(vectorVar.begin(),40000);
// TODO for_each 源码
// 参数 : _InputIterator __first, 开始位置
// _InputIterator __last, 结束位置
// _Function __f 算法规则
// template<typename _InputIterator, typename _Function>
// _Function
// for_each(_InputIterator __first, _InputIterator __last, _Function __f)
// {
// // concept requirements
// __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
// __glibcxx_requires_valid_range(__first, __last);
// for (; __first != __last; ++__first)
// __f(*__first);
// return __f; // N.B. [alg.foreach] says std::move(f) but it's redundant.
// }
for_each(vectorVar.begin(),vectorVar.end(),_F());
return 0;
}
2.2 transform 变化操作
// transform 算法包里面的 变化操作
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class _unary_op{
public:
int operator()(const int _frist){
return _frist +9 ; // 变化 : 每个元素 + 9
}
};
int main(){
vector<int> vectorVar;
vectorVar.insert(vectorVar.begin(),10000);
vectorVar.insert(vectorVar.begin(),20000);
vectorVar.insert(vectorVar.begin(),30000);
vectorVar.insert(vectorVar.begin(),40000);
// 参数:_InputIterator __first, 开始位置
// _InputIterator __last, 结束位置
// _OutputIterator __result, 迭代器result
// _UnaryOperation __unary_op 变化规则 每个数都+9
transform(vectorVar.begin(),vectorVar.end(),vectorVar.begin(),_unary_op());
for(auto it = vectorVar.begin();it != vectorVar.end(); it++){
cout << "transform 1 " << *it << endl;
}
cout << endl;
// TODO 第二种方式 定义一个新的vector接收
vector<int> vectorResult ;
vectorResult.resize(vectorVar.size()); // 定义vectorResult的大小
transform(vectorVar.begin(),vectorVar.end(),vectorResult.begin(),_unary_op());
for (auto it = vectorResult.begin(); it != vectorResult.end() ; it ++) {
cout << "transform 2 " << *it << endl;
}
return 0;
}
2.3 查找 find 和 find_if
// TODO 查找 find 和 find_if 算法包里的查找元素
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// TODO 2 find_if 需要自定义仿函数
class __pred{
public:
int number;
// 构造方法
__pred(int number):number(number){}
bool operator()(const int value){
return number == value;
}
};
int main(){
vector<int> vectorVar;
vectorVar.insert(vectorVar.begin(),10000);
vectorVar.insert(vectorVar.begin(),20000);
vectorVar.insert(vectorVar.begin(),30000);
vectorVar.insert(vectorVar.begin(),40000);
// TODO find的源码 : 就是对find_if的封装
// template<typename _InputIterator, typename _Tp>
// inline _InputIterator
// find(_InputIterator __first, // 开始位置
// _InputIterator __last, // 结束位置
// const _Tp& __val) // 需要查找的元素
// {
// // concept requirements
// __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
// __glibcxx_function_requires(_EqualOpConcept<
// typename iterator_traits<_InputIterator>::value_type, _Tp>)
// __glibcxx_requires_valid_range(__first, __last);
// 对find_if的封装
// return std::__find_if(__first, __last,
// __gnu_cxx::__ops::__iter_equals_val(__val));
// }
// TODO 方式一 : find 没有自定义仿函数
// auto it = find(vectorVar.begin(),vectorVar.end(),500);
// TODO find_if的源码
// find_if(_InputIterator __first, // 开始位置
// _InputIterator __last, // 结束位置
// _Predicate __pred) // 自定义仿函数
// {
// .... 监测工作而已
// return std::__find_if(__first, __last,
// __gnu_cxx::__ops::__pred_iter(__pred));
// }
// TODO 方式二 : find_if 有自定义仿函数 __pred
auto it = find_if(vectorVar.begin(),vectorVar.end(), __pred(30000));
if(it != vectorVar.end()){
cout << "查找到了!" <<endl;
}else{
cout << "没有找到" << endl;
}
return 0;
}
2.4 统计元素个数 count count_if
//TODO 算法包中的 统计元素个数 count count_if
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// TODO count 没有自定义仿函数
int main(){
vector<int> vectorVar;
vectorVar.insert(vectorVar.begin(),1);
vectorVar.insert(vectorVar.begin(),2);
vectorVar.insert(vectorVar.begin(),3);
vectorVar.insert(vectorVar.begin(),4);
vectorVar.insert(vectorVar.begin(),5);
vectorVar.insert(vectorVar.begin(),1);
vectorVar.insert(vectorVar.begin(),2);
vectorVar.insert(vectorVar.begin(),3);
vectorVar.insert(vectorVar.begin(),4);
vectorVar.insert(vectorVar.begin(),5);
int number = count(vectorVar.begin(),vectorVar.end(),2);
cout << "等于2的个数是:" << number << endl;
// TODO count_if
number = count_if(vectorVar.begin(),vectorVar.end(), bind2nd(less<int>(),2)); // < 2 的个数
cout << "小于2的个数是:" << number << endl;
number = count_if(vectorVar.begin(),vectorVar.end(), bind2nd(greater<int>(),2)); // > 2 的个数
cout << "大于2的个数是:" << number << endl;
number = count_if(vectorVar.begin(),vectorVar.end(), bind2nd(equal_to<int>(),2)); // == 2 的个数
cout << "等于2的个数是:" << number << endl;
return 0;
}
2.5 合并 merge
// 算法包里的 合并 merge
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
vector<int> vectorVar;
vectorVar.push_back(10);
vectorVar.push_back(20);
vectorVar.push_back(30);
vectorVar.push_back(40);
vectorVar.push_back(50);
vector<int> vectorVar1;
vectorVar1.push_back(60);
vectorVar1.push_back(70);
vectorVar1.push_back(80);
vectorVar1.push_back(90);
vectorVar1.push_back(100);
// 合并成一个容器
vector<int> vectorResult;
vectorResult.resize(vectorVar.size() + vectorVar1.size());
merge(vectorVar.begin(),vectorVar.end(),vectorVar1.begin(),vectorVar1.end(),vectorResult.begin());
for(auto it = vectorResult.begin(); it != vectorResult.end() ; it++){
cout << *it << endl;
}
return 0;
}
// TODO merge 的源码
// ....
//merge(_InputIterator1 __first1, _InputIterator1 __last1,
// _InputIterator2 __first2, _InputIterator2 __last2,
// _OutputIterator __result)
//{
// ....
// return _GLIBCXX_STD_A::__merge(__first1, __last1,
// __first2, __last2, __result,
// __gnu_cxx::__ops::__iter_less_iter());
//}
// TODO 点进:__merge
//__merge(_InputIterator1 __first1, _InputIterator1 __last1,
// _InputIterator2 __first2, _InputIterator2 __last2,
// _OutputIterator __result, _Compare __comp)
//{
// 做合并算法 处理的工作
// while (__first1 != __last1 && __first2 != __last2)
// {
// if (__comp(__first2, __first1))
// {
// *__result = *__first2;
// ++__first2;
// }
// else
// {
// *__result = *__first1;
// ++__first1;
// }
// ++__result;
// }
// return std::copy(__first2, __last2,
// std::copy(__first1, __last1, __result));
//}
2.6 sort 排序
// sort 算法包里的 排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
vector<int> vectorVar;
vectorVar.push_back(1);
vectorVar.push_back(2);
vectorVar.push_back(3);
vectorVar.push_back(6);
vectorVar.push_back(5);
vectorVar.push_back(4);
vectorVar.push_back(9);
vectorVar.push_back(5);
vectorVar.push_back(3);
vectorVar.push_back(7);
vectorVar.push_back(8);
vectorVar.push_back(1);
sort(vectorVar.begin(),vectorVar.end(), less<int>());
for (auto it = vectorVar.begin(); it != vectorVar.end(); it ++) {
cout << *it << endl;
}
return 0;
}
// TODO sort 源码
// ...
//sort(_RandomAccessIterator __first,
// _RandomAccessIterator __last,
// _Compare __comp) // 仿函数规则
//{
// //...
//
//
// std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp));
//}
// TODO 点进 __sort
//...
//__sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
// _Compare __comp)
//{
// 排序算法
// if (__first != __last)
// {
// std::__introsort_loop(__first, __last,
// std::__lg(__last - __first) * 2,
// __comp);
// std::__final_insertion_sort(__first, __last, __comp);
// }
//}
2.7 random_shuffle 随机打乱元素的顺序
// random_shuffle 算法包里面的 随机打乱元素的顺序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
vector<int> vectorVar;
vectorVar.push_back(65);
vectorVar.push_back(53);
vectorVar.push_back(84);
vectorVar.push_back(11);
vectorVar.push_back(22);
vectorVar.push_back(33);
vectorVar.push_back(44);
sort(vectorVar.begin(),vectorVar.end(),less<int>());
random_shuffle(vectorVar.begin(),vectorVar.end());
for(auto it = vectorVar.begin() ; it != vectorVar.end() ;it++){
cout << *it << endl;
}
return 0;
}
// TODO
// ...
//random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
//{
// // ....
//
// if (__first != __last)
// for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
// {
// // XXX rand() % N is not uniformly distributed
// _RandomAccessIterator __j = __first
// + std::rand() % ((__i - __first) + 1);
// if (__i != __j)
// std::iter_swap(__i, __j);
// }
//}
2.8 copy
//TODO copy copy容器1 的元素 到容器2
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
vector<int> vectorVar;
vectorVar.push_back(100);
vectorVar.push_back(200);
vectorVar.push_back(300);
vectorVar.push_back(400);
vectorVar.push_back(500);
vectorVar.push_back(600);
vectorVar.push_back(700);
vector<int> vectorResult;
vectorResult.resize(vectorVar.size());
copy(vectorVar.begin(),vectorVar.end(),vectorResult.begin());
// 打印
for (auto it = vectorResult.begin(); it != vectorResult.end() ; it++) {
cout << *it << endl;
}
return 0;
}
2.9 replace 替换元素内容
// TODO replace 替换元素内容
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int age;
void set(int age){
::age = age;
}
int main(){
vector<int> vectorVar;
vectorVar.push_back(100);
vectorVar.push_back(200);
vectorVar.push_back(300);
vectorVar.push_back(400);
vectorVar.push_back(500);
vectorVar.push_back(600);
// 100 - 200 的范围
replace(vectorVar.begin(),vectorVar.begin() + 2,200,222);
// 所有范围
replace(vectorVar.begin(),vectorVar.end(),300,333);
for(auto itVar = vectorVar.begin() ; itVar != vectorVar.end();itVar++){
cout << *itVar << endl;
}
return 0;
}