C++提高编程(黑马笔记)

嵌入式面经篇八——进程&线程 记录一些招聘公司在招聘嵌入式软件岗位时的一些问题,此文为第八篇。进程上文:是指进程由用户态切换到内核态时需要保存用户态时CPU寄存器中的值,进程状态以及堆栈上的内容。即保存当前进程的状态,以便再次执行该进程时,能够恢复切换时的状态,继续执行。进程下文:是指切换到内核态后执行的程序,即进程运行在内核空间的部分。中断上文:硬件通过中断触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。 阅读详情

C++提高编程

模版

特点:

  • 只是一个框架,不可以直接使用
  • 通用并不是万能的

泛型主要利用模版

函数模版

语法:

template<typename T>
函数
# include<iostream>
using namespace std;

template<typename T>
void MySwap(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}

void test01() {
	int a = 10;
	int b = 20;
	MySwap(a, b);
	cout << a << " " << b << endl;
	char c = 'a';
	char d = 'b';
	MySwap<char>(c, d);
	cout << c << " " << d << endl;
}

int main() {
	test01();
	system("pause");
	return 0;
}

注意事项:

  • 自动类型推导,必须推导出一致的数据类型T,才可以使用
  • 模版必须确定出T的数据类型才可以使用
# include<iostream>
using namespace std;

template<typename T>
void MySwap(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}

template<class T>
void func() {
	cout << "func" << endl;
}

void test01() {
	int a = 10;
	int b = 20;
	MySwap(a, b);
	char c = 'a';
	//MySwap(c, a);
	//func();
	func<int>();
}

int main() {
	test01();
	system("pause");
	return 0;
}

普通函数与函数模版的区别:

  • 普通函数可以发生自动类型转换
  • 函数模版调用时,如果利用自动类型推导,不会发生自动类型转换
  • 如果利用显示指定类型的方式,可以发生自动类型转换
# include<iostream>
using namespace std;

template<typename T>
T MyAdd1(T a, T b) {
	return a + b;
}

int MyAdd2(int a, int b) {
	return a + b;
}

void test01() {
	int a = 10;
	int b = 20;
	char c = 'a'; // 97
	int ans = 0;
	ans = MyAdd2(a, c);
	cout << ans << endl;
	//ans = MyAdd1(a, c);
	ans = MyAdd1<int>(a, c);
	cout << ans << endl;
}

int main() {
	test01();
	system("pause");
	return 0;
}

普通函数与函数模版的调用规则:

  1. 都可实现,优先调用普通函数
  2. 可以通过空模版参数列表来强制调用函数模版
  3. 函数模版也可以重载
  4. 如果函数模版可以更好的匹配,优先调用函数模版
# include<iostream>
using namespace std;

void MySwap(int &a, int &b) {
	cout << "普通函数" << endl;
}

template<typename T>
void MySwap(T &a, T &b) {
	cout << "函数模版" << endl;
}

template<typename T>
void MySwap(T& a, T& b, int x) {
	cout << "重载函数模版" << endl;
}

void test01() {
	int a = 10;
	int b = 2;
	MySwap(a, b);
	MySwap<>(a, b);
	MySwap(a, b, 100);
	char c = 'a';
	char d = 'b';
	MySwap(c, d);
}

int main() {
	test01();
	system("pause");
	return 0;
}

局限性:

  • 传入class类时,需要进行函数模版的重载
# include<iostream>
# include<string>
using namespace std;

class Person {
public:
	Person(string name, int age) {
		this->m_name = name;
		this->m_age = age;
	}
	string m_name;
	int m_age;
};

template<typename T>
bool MyCompare(T &a, T &b) {
	if (a == b) {
		return true;
	}
	return false;
}


template<> bool MyCompare(Person & a, Person & b) {
	if (a.m_age == b.m_age && a.m_name == b.m_name) {
		return true;
	}
	return false;
}

void test01() {
	Person p1("张三", 19);
	Person p2("罗向", 55);
	Person p3("张三", 19);
	if (MyCompare(p1, p2)) {
		cout << "p1 p2 一样" << endl;
	}
	else {
		cout << "p1 p2 不一样" << endl;
	}
	if (MyCompare(p1, p3)) {
		cout << "p1 p3 一样" << endl;
	}
	else {
		cout << "p1 p3 不一样" << endl;
	}
}

int main() {
	test01();
	system("pause");
	return 0;
}

类模版

语法:

template<typename T>
类
# include<iostream>
# include<string>
using namespace std;

template <class NameType, class AgeType>
class Person {
public:
	Person(NameType name, AgeType age) {
		this->m_name = name;
		this->m_age = age;
	}
	void show() {
		cout << m_name << " " << m_age << endl;
	}
	NameType m_name;
	AgeType m_age;
};

void test01() {
	Person<string, int> p("孙悟空", 999);
	p.show();
}

int main() {
	test01();
	system("pause");
	return 0;
}

类模版与函数模版区别:

类模版与函数模版区别主要有两点:

  1. 类模版没有自动类型推导的使用方式
  2. 类模版在模版参数列表中可以有默认参数
# include<iostream>
# include<string>
using namespace std;

template <class NameType, class AgeType = int>
class Person {
public:
	Person(NameType name, AgeType age) {
		this->m_name = name;
		this->m_age = age;
	}
	void show() {
		cout << m_name << " " << m_age << endl;
	}
	NameType m_name;
	AgeType m_age;
};

void test01() {
	//Person p("孙悟空", 999);
	Person<string> p("财务科", 98);
	p.show();
}

int main() {
	test01();
	system("pause");
	return 0;
}

类模版中成员函数创建时机:

  • 普通类中成员函数一开始就可以创建
  • 类模版中成员函数在调用时才创建
# include<iostream>
# include<string>
using namespace std;

class Person1 {
public:
	void show1() {
		cout << 1 << endl;
	}
};

class Person2 {
public:
	void show2() {
		cout << 2 << endl;
	}
};

template<class T>
class MyClass {
public:
	T obj;
	void func1() {
		obj.show1();
	}
	void func2() {
		obj.show2();
	}
};

void test01() {
	MyClass<Person1> c;
	c.func1();
	//c.func2();
}

int main() {
	test01();
	system("pause");
	return 0;
}

类模版对象做函数参数:

三种传入方式:

  1. 指定传入的类型(直接显示对象的数据类型)
  2. 参数模版化(将对象中的参数变为模版进行传递)
  3. 整个类模版化(将这个对象类型 模版化进行传递)
# include<iostream>
# include<string>
using namespace std;

template<class T1, class T2>
class Person {
public:
	Person(T1 name, T2 age) {
		this->m_name = name;
		this->m_age = age;
	}
	void showPerson() {
		cout << m_name << " " << m_age << endl;
	}
	T1 m_name;
	T2 m_age;
};

void show1(Person<string, int> &p) {
	p.showPerson();
}

template<class T1, class T2>
void show2(Person<T1, T2> &p) {
	p.showPerson();
}

template<class T> 
void show3(T& p) {
	p.showPerson();
}

void test01() {
	Person<string, int> p("孙悟空", 999);
	show1(p);
	show2(p);
	show3(p);
}

int main() {
	test01();
	system("pause");
	return 0;
}

类模版与继承:

注意事项:

  • 当子类继承的父类是一个类模版时,子类在声明的时候,要指定出父类中的T类型
  • 如果不指定,编译器无法给子类分配内存
  • 如果想灵活指定出父类中T的类型,子类也虚变为类模版
# include<iostream>
# include<string>
using namespace std;

template<class T> 
class Base {
public:
	T m;
};

class Son1 : public Base<int> {

};

template<class T1, class T2>
class Son2 : public Base<T2> {
	T1 obj;
};

void test01() {
	Son2<int, char> s2;
}

int main() {
	test01();
	system("pause");
	return 0;
}

类模版成员函数类外实现:

# include<iostream>
# include<string>
using namespace std;

template<class T1, class T2>
class Person {
public:
	Person(T1 name, T2 age);
	void showPerson();
	T1 m_name;
	T2 m_age;
};

template<class T1, class T2> 
Person<T1, T2>::Person(T1 name, T2 age) {
	this->m_name = name;
	this->m_age = age;
}

template<class T1, class T2>
void Person<T1, T2>::showPerson() {
	cout << m_name << " " << m_age << endl;
}

void test01() {
	Person<string, int> p("猪八戒", 888);
	p.showPerson();
}

int main() {
	test01();
	system("pause");
	return 0;
}

类模版分文件编写:

问题:类模版中成员函数创建时机是在调用阶段,导致分文件编写时链接不到

解决:

  • 直接包含.cpp源文件
  • 将声明和实现写到同一个文件中,更改后缀名为.hpp

person.h

#pragma once
# include<iostream>
# include<string>
using namespace std;

template<class T1, class T2>
class Person {
public:
	Person(T1 name, T2 age);
	void showPerson();
	T1 m_name;
	T2 m_age;
};

person.cpp

#include "person.h"
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) {
	this->m_name = name;
	this->m_age = age;
}

template<class T1, class T2>
void Person<T1, T2>::showPerson() {
	cout << m_name << " " << m_age << endl;
}

main.cpp

# include<iostream>
# include<string>
# include "person.cpp"
using namespace std;

void test01() {
	Person<string, int> p("猪八戒", 888);
	p.showPerson();
}

int main() {
	test01();
	system("pause");
	return 0;
}

person.hpp

#pragma once
# include<iostream>
# include<string>
using namespace std;

template<class T1, class T2>
class Person {
public:
	Person(T1 name, T2 age);
	void showPerson();
	T1 m_name;
	T2 m_age;
};

template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) {
	this->m_name = name;
	this->m_age = age;
}

template<class T1, class T2>
void Person<T1, T2>::showPerson() {
	cout << m_name << " " << m_age << endl;
}

main.cpp

# include<iostream>
# include<string>
# include "person.hpp"
using namespace std;

void test01() {
	Person<string, int> p("猪八戒", 888);
	p.showPerson();
}

int main() {
	test01();
	system("pause");
	return 0;
}

类模版与友元:

# include<iostream>
# include<string>
using namespace std;

template<class T1, class T2>
class Person;

template<class T1, class T2>
void showPerson2(Person<T1, T2> &p) {
	cout << p.m_name << " " << p.m_age << endl;
}

template<class T1, class T2>
class Person {
	//类内实现
	friend void showPerson(Person<T1, T2> &p) {
		cout << p.m_name << " " << p.m_age << endl;
	};
	//类外实现
	friend void showPerson2<>(Person<T1, T2> &p);
public:
	Person(T1 name, T2 age) {
		this->m_name = name;
		this->m_age = age;
	};
private:
	T1 m_name;
	T2 m_age;
};

void test01() {
	Person<string, int> p("猪八", 888);
	showPerson2(p);
}

int main() {
	test01();
	system("pause");
	return 0;
}

STL

基本概念

  • STL广义上分为,容器,算法,迭代器
  • 容器和算法之间通过迭代器进行无缝连接

六大组件:

容器,算法,迭代器,仿函数,适配器(配接器),空间配置器

  1. 容器:各种数据结构
  2. 算法:各种常用算法
  3. 迭代器:容器与算法之间的胶合剂
  4. 仿函数:行为类似函数,算法的某种策略
  5. 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西
  6. 空间配置器:负责空间的配置与管理

容器:

  • 序列式容器:强调值的排序
  • 关联式容器:二叉树结构

算法:

  • 质变算法:运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等
  • 非质变算法:运算过程中不会更改区间内的元素的内容。例如查找,计数,遍历等

迭代器:

种类功能支持运算
输入迭代器只读数据只读,支持++ == ! =
输出迭代器只写数据只写,支持++
前向迭代器读写操作,向前推进迭代器读写,支持++ == ! =
双向迭代器读写操作,向前和向后操作读写,支持++ –
随机访问迭代器读写操作,跳跃访问任意数据读写,支持++ – [n] -n < <= > >=

vector存放内置数据类型:

容器:vector

算法:for_each

迭代器:vector<int>::iterator

# include<iostream>
# include<string>
# include<vector>
# include<algorithm>
using namespace std;

void MyPrint(int val) {
	cout << val << endl;
}

void test01() {
	vector<int> v;
	v.push_back(10);
	v.push_back(23);
	v.push_back(90);
	//第一种
	vector<int>::iterator isBegin = v.begin();
	vector<int>::iterator isEnd = v.end();
	while (isBegin != isEnd) {
		cout << *isBegin << endl;
		isBegin++;
	}
	//第二种
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << endl;
	}
	//第三种
	for_each(v.begin(), v.end(), MyPrint);
}

int main() {
	test01();
	system("pause");
	return 0;
}

vector存放自定义数据类型:

# include<iostream>
# include<string>
# include<vector>
# include<algorithm>
using namespace std;

class Person {
public:
	Person(string name, int age) {
		this->m_age = age;
		this->m_name = name;
	}
	string m_name;
	int m_age;
};
void test01() {
	vector<Person> v1;
	Person p1("a", 10);
	Person p2("b", 101);
	v1.push_back(p1);
	v1.push_back(p2);
	for (vector<Person>::iterator it = v1.begin(); it != v1.end(); it++) {
		cout << (*it).m_name << " " << (*it).m_age << endl;
		cout << it->m_name << " " << it->m_age << endl;
	}
	vector<Person*> v2;
	Person p3("c", 10);
	Person p4("d", 101);
	v2.push_back(&p3);
	v2.push_back(&p4);
	for (vector<Person*>::iterator it = v2.begin(); it != v2.end(); it++) {
		cout << (*it)->m_name << " " << (*it)->m_age << endl;
	}
}

int main() {
	test01();
	system("pause");
	return 0;
}

容器嵌套容器:

# include<iostream>
# include<string>
# include<vector>
# include<algorithm>
using namespace std;

void test01() {
	vector<vector<int>> v;
	vector<int> v1;
	vector<int> v2;
	v1.push_back(1);
	v1.push_back(2);
	v2.push_back(3);
	v2.push_back(5);
	v.push_back(v1);
	v.push_back(v2);
	for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++) {
		for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++) {
			cout << *vit << " ";
		}
		cout << endl;
	}
}

int main() {
	test01();
	system("pause");
	return 0;
}

string容器

本质:一个类

string与char*区别:

  • char*是一个指针
  • string是一个类,类内部封装了char*,管理这个字符串,是一个char*的容器

构造函数:

  • string();
  • string(const char* s);
  • string(const string& str);
  • string(int n, char c)
void test01() {
	string s1;
	const char* str = "abc";
	string s2(str);
	cout << s2 << endl;
	string s3(s2);
	cout << s3 << endl;
	string s4(10, 'c');
	cout << s4 << endl;
}

赋值操作:

  • string& operator=(const char* s);
  • string& operator=(const string &s);
  • string& operator=(char c);
  • string& assign(const char *s);
  • string& assign(const char *s, int n);
  • string& assign(const string &s);
  • string& assign(int n, char c);
void test01() {
	string s1;
	s1 = "abc";
	cout << s1 << endl;
	string s2 = s1;
	cout << s2 << endl;
	string s3, s4, s5, s6;
	s3.assign(s1);
	cout << s3 << endl;
	s4.assign(s1, 2);
	cout << s4 << endl;
	s5.assign("abh");
	cout << s5 << endl;
	s6.assign(10, 'e');
	cout << s6 << endl;
}

字符串拼接:

  • string& operator+=(const char* str);
  • string& operator+=(const char c);
  • string& operator+=(const string& str);
  • string& append(const char* s);
  • string& append(const char* s, int n);
  • string& append(const string &s);
  • string& append(const string &s, int pos, int n);
void test01() {
	string s1, s2, s3, s4, s5, s6;
	s1 = "c";
	s1 += "abc";
	cout << s1 << endl;
	s1 += 'm';
	cout << s1 << endl;
	s1 += s1;
	cout << s1 << endl;
	s2 = "l";
	s2.append("hj");
	cout << s2 << endl;
	s2.append("abhasahdjhsady", 9);
	cout << s2 << endl;
	s2.append(s1);
	cout << s2 << endl;
	s2.append(s1, 3, 2);
	cout << s2 << endl;
}

查找和替换:

  • int find(const string& str, int pos = 0) const;
  • int find(const char* s, int pos = 0) const;
  • int find(const char* s, int pos = 0, int n) const;
  • int find(const char c, int pos = 0) const;
  • int rfind(const string& str, int pos = npos) const;
  • int rfind(const char* s, int pos = npos) const;
  • int rfind(const char* s, int pos, int n) const;
  • int rfind(const char c, int pos = 0) const;
  • string& replace(int pos, int n, const string& str);
  • string& replace(int pos, int n, const char* s);
void test01() {
	string s1, s2, s3, s4, s5, s6;
	s1 = "abcdefg";
	int ans = 0;
	ans = s1.find("c");
	ans = s1.find("fj");
	ans = s1.rfind("de"); // 从右往左
	cout << ans << endl;
	s1.replace(1, 4, "11111");
	cout << s1 << endl;
}

字符串比较:

按ASCLL码进行对比

  • = 返回 0
  • > 返回 1
  • < 返回 -1

原型:

  • int compare(const string &s) const;
  • int compare(const char *s) const;
void test01() {
	string s1, s2, s3, s4, s5, s6;
	s1 = "abcdefg";
	s2 = "abcdefg";
	s3 = "zzz";
	s4 = "aaa";
	int ans = 0;
	ans = s1.compare(s2);
	ans = s1.compare(s3);
	ans = s1.compare(s4);
	cout << ans << endl;
}

字符存取:

  • char& operator[](int n);
  • char& at(int n);
void test01() {
	string s1, s2, s3, s4, s5, s6;
	s1 = "abcdefg";
	for (int i = 0; i < s1.size(); i++) {
		cout << s1[i] << " " << s1.at(i) << endl;
	}
}

插入和删除:

  • string& insert(int pos, const char* s);
  • string& insert(int pos, const string& s);
  • string& insert(int pos, int n, char c);
  • string& erase(int pos, int n = npos);
void test01() {
	string s1, s2, s3, s4, s5, s6;
	s1 = "abcdefg";
	s2 = "cde";
	s1.insert(2,"zzz");
	s1.insert(3, s2);
	s1.insert(1, 10, 'a');
	s1.erase(1, 10);
	cout << s1 << endl;
}

子串:

  • string substr(int pos = 0, int n = npos) const
void test01() {
	string s1, s2, s3, s4, s5, s6;
	s1 = "abcdefg";
	s2 = s1.substr(3, 5);
	cout << s2 << endl;
}

vector容器

与数组非常相似,也称为单端数组,与数组的区别是可以动态扩展

动态扩展:

  • 不是在原空间之后接新空间,而是找更大的内存空间,将原数据拷贝到新空间

在这里插入图片描述

构造函数:

  • vector<T> v;
  • vector(v.begin(), v.end());
  • vector(n, elem);
  • vector(const vector &vec)
void test01() {
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	PrintVector(v1);
	vector<int> v2(v1.begin(), v1.end());
	PrintVector(v2);
	vector<int> v3(10, 10);
	PrintVector(v3);
	vector<int> v4(v3);
	PrintVector(v4);
}

赋值操作:

  • vector& operator=(const vector &vec);
  • assign(beg, end);
  • assign(n, elem);
void test01() {
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	PrintVector(v1);
	vector<int> v2 = v1;
	PrintVector(v2);
	vector<int> v3, v4;
	v3.assign(v2.begin(), v2.end());
	PrintVector(v3);
	v4.assign(10, 12);
	PrintVector(v4);
}

容量和大小:

  • empty();
  • capacity();
  • size();
  • resize(int num);
  • resize(int num, elem);
void test01() {
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	PrintVector(v1);
	if (v1.empty()) {
		cout << "空" << endl;
	}
	else {
		cout << v1.size() << endl;
		cout << v1.capacity() << endl;
	}
	v1.resize(20);
	cout << v1.size() << " " << v1.capacity() << endl;
}

插入和删除:

  • push_back(ele);
  • pop_back();
  • insert(const_iterator pos, ele);
  • insert(const_iterator pos, int count, ele);
  • erase(const_iterator pos);
  • erase(const_iterator start, const_iterator end);
  • clear();
void test01() {
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	PrintVector(v1);
	v1.pop_back();
	PrintVector(v1);
	v1.insert(v1.begin(), 2, 'c');
	PrintVector(v1);
	v1.erase(v1.begin());
	PrintVector(v1);
}

数据存取:

  • at(int idx);
  • operator[];
  • front();
  • back();
void test01() {
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
		v1.push_back(i);
	}
	PrintVector(v1);
	cout << v1.at(3) << " " << v1[8] << endl;
	cout << v1.front() << " " << v1.back() << endl;
}

互换容器与预留空间:

  • swap(vec);
  • reserve(int len);
void test01() {
	vector<int> v1, v2;
	v1.reserve(100000);
	int cnt = 0;
	int* p = NULL;
	for (int i = 0; i < 100000; i++) {
		v1.push_back(i);
		if (p != &v1[0]) {
			p = &v1[0];
			cnt++;
		}
	}
	cout << cnt << endl;
	//PrintVector(v1);
	//for (int i = 100; i >= 90; i--) {
	//	v2.push_back(i);
	//}
	//PrintVector(v2);
	//v1.swap(v2);
	//PrintVector(v1);
	//PrintVector(v2);
}

deque容器

双端数组,可以对头端进行插入删除操作

deque与vector区别:

  • deque对头部的插入删除速度快
  • vector访问元素的速度快

在这里插入图片描述

工作原理:

deque内部有中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据

中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间

在这里插入图片描述

构造函数:

  • deque<T>
  • deque(beg, end);
  • deque(n, else);
  • deque(const deque &deq);
void test01() {
	deque<int> q1;
	for (int i = 0; i < 10; i++) {
		q1.push_back(i);
	}
	Print(q1);
	deque<int> q2(q1.begin(), q1.end());
	Print(q2);
	deque<int> q3(10, 100);
	Print(q3);
	deque<int> q4(q3);
	Print(q4);
}

赋值操作:

  • deque& operator=(const deque &deq);
  • assign(beg, end);
  • assign(n, elem);
void test01() {
	deque<int> q1, q2, q3, q4;
	for (int i = 0; i < 10; i++) {
		q1.push_back(i);
	}
	Print(q1);
	q2 = q1;
	Print(q2);
	q3.assign(q1.begin(), q1.end());
	Print(q3);
	q4.assign(10, 100);
	Print(q4);
}

大小操作:

  • deque.empty();
  • deque.size();
  • deque.resize(num);
  • deque.resize(num, elem);
void test01() {
	deque<int> q1, q2, q3, q4;
	for (int i = 0; i < 10; i++) {
		q1.push_back(i);
	}
	Print(q1);
	if (q1.empty()) {
		cout << "空" << endl;
	}
	else {
		//deque没有容量的概念
		cout << q1.size() << endl;
		q1.resize(20);
		cout << q1.size() << endl;
	}
}

插入删除:

  • push_back(elem);
  • push_front(elem);
  • pop_back();
  • pop_front();
  • insert(pos, elem);
  • insert(pos, n, elem);
  • insert(pos, beg, end);
  • clear();
  • erase(beg, end);
  • erase(pos);
void test01() {
	deque<int> q1, q2, q3, q4;
	for (int i = 0; i < 10; i++) {
		q1.push_back(i);
		q2.push_front(i);
	}
	PrintDeque(q1);
	q1.push_front(2);
	PrintDeque(q1);
	q1.pop_front();
	q1.pop_back();
	PrintDeque(q1);
	q1.insert(q1.begin(), 99);
	PrintDeque(q1);
	q1.insert(q1.begin(), 10, 99);
	PrintDeque(q1);
	q1.insert(q1.begin(), q2.begin(), q2.end());
	PrintDeque(q1);
	q1.erase(q2.begin(), q2.end());
	PrintDeque(q1);
}

数据存取与排序:

  • at(int idx);
  • operator[];
  • front();
  • back();
  • sort(iterator beg, iterator end);
void test01() {
	deque<int> q1, q2, q3, q4;
	for (int i = 0; i < 10; i++) {
		q1.push_back(i);
		q1.push_back(i + 10);
	}
	PrintDeque(q1);
	cout << q1.at(2) << " " << q1[3] << endl;
	cout << q1.front() << " " << q1.back() << endl;
	sort(q1.begin(), q1.end());
	PrintDeque(q1);
}

stack容器

在这里插入图片描述

构造函数与赋值:

  • stack<T> stk;
  • stack(const stack &stk);
  • stack& operator=(const stack &stk);

数据存取与大小操作:

  • push(elem);
  • pop();
  • top();
  • empty();
  • size();
void test01() {
	stack<int> s1, s2;
	for (int i = 0; i < 10; i++) {
		s1.push(i);
	}
	s2 = s1;
	while (!s1.empty()) {
		cout << s1.top() << " " << s1.size() << endl;
		s1.pop();
	}
}

queue容器

在这里插入图片描述

构造函数:

  • queue<T> que;
  • queue(const queue &que);

赋值操作:

  • queue& operator=(const queue &que);

数据存取:

  • push(elem);
  • pop();
  • back();
  • front();

大小操作:

  • empty();
  • size();
void test01() {
	queue<int> q1, q2;
	for (int i = 0; i < 10; i++) {
		q1.push(i);
	}
	while (!q1.empty()) {
		cout << q1.front() << " " << q1.back() << " " << q1.size() << endl;
		q1.pop();
	}	
}

list容器

在这里插入图片描述

优点:

  • 动态内存分配,不会内存浪费和溢出
  • 插入和删除便利,不会造成原有迭代器失效

缺点:

  • 空间时间额外消耗大

构造函数:

  • list<T> list;
  • list(beg, end);
  • list(n, elem);
  • list(const list &lst);
void test01() {
	list<char> list1, list2;
	list<char> list3(10, 'c');
	list<char> list4(list3);
}

赋值和交换:

  • assign(beg, end);
  • assign(n, elem);
  • list& operator=(const list &lst);
  • swap(lst);
void test01() {
	list<char> list1, list2;
	list<char> list3(10, 'c');
	list<char> list4(list3);
	list1.assign(list3.begin(), list3.end());
	list2.assign(10, 'b');
	PrintList(list1);
	PrintList(list2);
	PrintList(list3);
	swap(list2, list3);
	PrintList(list2);
	PrintList(list3);
}

大小操作:

  • size();
  • empty();
  • resize(num);
  • resize(num, elem);
void test01() {
	list<int> list1, list2;
	for (int i = 0; i < 10; i++) {
		list1.push_back(i);
	}
	PrintList(list1);
	if (list1.empty()) {
		cout << "空" << endl;
	}
	else {
		cout << list1.size() << endl;
		list1.resize(20, 0);
	}
	cout << list1.size() << endl;
	PrintList(list1);
}

插入删除:

  • push_back(elem);
  • pop_back();
  • push_front(elem);
  • pop_front();
  • insert(pos, elem);
  • insert(pos, n, elem);
  • insert(pos, beg, end);
  • clear();
  • erase(beg, end);
  • erase(pos);
  • remove(elem);
void test01() {
	list<int> list1, list2;
	for (int i = 0; i < 10; i++) {
		list1.push_back(i);
		list1.push_back(19);
	}
	PrintList(list1);
	list1.push_front(99);
	list1.remove(19);
	PrintList(list1);
	list1.pop_front();
	list1.pop_back();
	PrintList(list1);
	list1.insert(list1.end(), 9);
	list1.insert(list1.end(), 9);
	PrintList(list1);
	list<int>::iterator it = list1.end();
	it--;
	list1.erase(it);
	PrintList(list1);
}

数据存取与反转排序:

  • front();
  • back();
  • reverse();
  • sort();
void test01() {
	list<int> list1, list2;
	for (int i = 0; i < 10; i++) {
		list1.push_back(i);
		list1.push_back(i + 10);
	}
	PrintList(list1);
	cout << list1.front() << " " << list1.back() << endl;
	list1.reverse();
	PrintList(list1);
	list1.sort();
	PrintList(list1);
}

set/multiset容器

本质:关联式容器,底层用二叉树实现

区别:

  • set不允许有重复元素,multiset允许

构造和赋值:

  • set<T> st;
  • set(const set &st);
  • set& operator=(const set &st);
void test01() {
	set<int> s1;
	set<int> s2(s1);
	set<int> s3 = s1;
}

大小和交换:

  • size();
  • empty();
  • swap(st);
void test01() {
	set<int> s1, s2;
	for (int i = 0; i < 10; i++) {
		s1.insert(i);
		s2.insert(i + 10);
	}
	PrintSet(s1);
	PrintSet(s2);
	if (s1.empty()) {
		cout << "空" << endl;
	}
	else {
		cout << s1.size() << endl;
	}
	s1.swap(s2);
	PrintSet(s1);
	PrintSet(s2);
}

插入删除:

  • insert(elem);
  • clear();
  • erase(pos);
  • erase(beg, end);
  • erase(elem);
void test01() {
	set<int> s1, s2;
	for (int i = 0; i < 10; i++) {
		s1.insert(i);
		s2.insert(i + 10);
	}
	PrintSet(s1);
	PrintSet(s2);
	s2.erase(19);
	PrintSet(s2);
}

查找统计:

  • find(key);
  • count(key);
void test01() {
	set<int> s1, s2;
	for (int i = 0; i < 10; i++) {
		s1.insert(i);
		s2.insert(i + 10);
	}
	PrintSet(s1);
	PrintSet(s2);
	set<int>::iterator it = s1.find(6);
	cout << *it << endl;
	if (s1.find(90) != s1.end()) {
		cout << "找到90" << endl;
	}
	else {
		cout << "找不到90" << endl;
	}
	cout << s1.count(15) << " " << s2.count(15) << endl;
}

pair对组创建:

  • pair<type, type> p (v1, v2);
  • pair<type, type> p = make_pair (v1, v2);
void test01() {
	pair<string, int> p1("Tom", 11);
	cout << p1.first << " " << p1.second << endl;
	pair<string, int> p2 = make_pair("Steve", 18);
	cout << p2.first << " " << p2.second << endl;
}

排序:

  • 默认排序规则为从小到大
class MyCompare {
public:
	bool operator()(int v1, int v2)const {
		return v1 > v2;
	}
};

void test01() {
	set<int> s1, s2;
	s1.insert(10);
	s1.insert(40);
	s1.insert(20);
	s1.insert(90);
	PrintSet(s1);
	set<int, MyCompare> s3;
	s3.insert(10);
	s3.insert(40);
	s3.insert(20);
	s3.insert(90);
	for (set<int, MyCompare>::iterator it = s3.begin(); it != s3.end(); it++) {
		cout << (*it) << " ";
	}
	cout << endl;
}

map/multimap容器

简介:

  • 所有元素都是pair
  • 第一个元素为key,第二个元素是value
  • 根据value自动排序

本质:

  • 关联式容器,底层用二叉树实现

区别:

  • map不允许重复key值元素
  • multimap允许重复key元素

构造赋值:

  • map<T1, T2> mp;
  • map(const map &mp);
  • map& operator=(const map &mp);
void test01() {
	map<int, char> m1;
	map<int, char> m2(m1);
	map<int, char> m3 = m2;
}

大小交换:

  • size();
  • empty();
  • swap(st);
void test01() {
	map<int, char> m1, m2;
	m1.insert(pair<int, char>(1, 'a'));
	m1.insert(pair<int, char>(2, 'c'));
	m1.insert(pair<int, char>(3, 'b'));
	if (m1.empty()) {
		cout << "空" << endl;
	}
	else {
		PrintMap(m1);
		cout << m1.size() << endl;
	}
	m2.insert(pair<int, char>(1, 'p'));
	m2.insert(pair<int, char>(2, 'm'));
	m2.insert(pair<int, char>(3, 'n'));
	m1.swap(m2);
	PrintMap(m1);
	PrintMap(m2);
}

插入删除:

  • insert(elem);
  • clear();
  • erase(pos);
  • erase(beg, end);
  • erase(key);
void test01() {
	map<int, char> m1, m2;
	m1.insert(pair<int, char>(1, 'a'));
	m1.insert(pair<int, char>(2, 'c'));
	m1.insert(pair<int, char>(3, 'b'));
	m2.insert(pair<int, char>(1, 'p'));
	m2.insert(pair<int, char>(2, 'm'));
	m2.insert(pair<int, char>(3, 'n'));
	PrintMap(m2);
	m2.erase(2);
	PrintMap(m2);
	m2.erase(m2.begin());
	PrintMap(m2);
}

查找统计:

  • find(key);
  • count(key);
void test01() {
	map<int, char> m1, m2;
	m2.insert(pair<int, char>(1, 'p'));
	m2.insert(pair<int, char>(2, 'm'));
	m2.insert(pair<int, char>(3, 'n'));
	m2.insert(pair<int, char>(4, 'p'));
	PrintMap(m2);
	map<int, char>::iterator pos = m2.find(2);
	cout << (*pos).first << " " << (*pos).second << endl;
	cout << m2.count(1) << endl;
}

排序:

void test01() {
	map<int, int> m1, m2;
	m2.insert(pair<int, int>(1, 10));
	m2.insert(pair<int, int>(2, 30));
	m2.insert(pair<int, int>(3, 20));
	m2.insert(pair<int, int>(4, 40));
	PrintMap(m2);
	map<int, int, MyCompare> m3;
	m3.insert(pair<int, int>(1, 10));
	m3.insert(pair<int, int>(2, 30));
	m3.insert(pair<int, int>(3, 20));
	m3.insert(pair<int, int>(4, 40));
	for (map<int, int, MyCompare>::iterator it = m3.begin(); it != m3.end(); it++) {
		cout << (*it).second << " ";
	}
	cout << endl;
}

函数对象

概念:

  • 重载函数调用操作符的类,其对象称为函数对象
  • 函数对象使用重载的()时,行为类似函数调用,也叫仿函数

本质:

函数对象(仿函数)是一个类,不是一个函数

特点:

  • 可以像普通函数一样使用
  • 可以有自己的状态
  • 可以作为参数传递
class MyAdd {
public:
	int operator()(int v1, int v2) {
		return v1 + v2;
	}
};

class MyPrint {
public:
	MyPrint() {
		this->cnt = 0;
	}
	void operator()(string test) {
		cout << test << endl;
		this->cnt++;
	}
	int cnt;
};

void doPrint(MyPrint p, string text) {
}

void test01() {
	MyAdd m;
	cout << m(10, 11) << endl;
	MyPrint p;
	p("hello");
	p("hello");
	p("hello");
	cout << p.cnt << endl;
	doPrint(p, "helloo");
}

谓词:

  • 返回bool类型的仿函数称为谓词
  • 如果operator()接受一个参数,那么叫做一元谓词
  • 如果operator()接受两个参数,那么叫做二元谓词
class JudgeFour {
public:
	bool operator()(int v) {
		return v > 4;
	}
};


void test01() {
	vector<int> v;
	for (int i = 0; i < 6; i++) {
		v.push_back(i);
	}
	vector<int>::iterator it = find_if(v.begin(), v.end(), JudgeFour());
	if (it == v.end()) {
		cout << "没找到" << endl;
	}
	else {
		cout << *it << endl;
	}
}
class JudgeFour {
public:
	bool operator()(int v1, int v2) {
		return v1 > v2;
	}
};


void test01() {
	vector<int> v;
	for (int i = 0; i < 6; i++) {
		v.push_back(i);
	}
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
	sort(v.begin(), v.end(), JudgeFour());
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

内建函数对象:

分类:

  • 算术仿函数
  • 关系仿函数
  • 逻辑仿函数

用法:

  • 这些仿函数所产生的对象,用法和一般函数完全相同
  • 引入头文件#include<functional>

算术仿函数:

  • template<class T> T plus<T> 加法
  • template<class T> T minus<T> 减法
  • template<class T> T multiplies<T> 乘法
  • template<class T> T divides<T> 除法
  • template<class T> T modulus<T> 取模
  • template<class T> T negate<T> 取反
void test01() {
	plus<int> p;
	cout << p(10, 20) << endl;
	minus<int> mi;
	cout << mi(30, 20) << endl;
	multiplies<int> mu;
	cout << mu(2, 90) << endl;
	divides<int> d;
	cout << d(90, 2) << endl;
	modulus<int> mo;
	cout << mo(99, 2) << endl;
	negate<int> n;
	cout << n(9) << endl;
}

关系仿函数:

  • template<class T> bool equal_to<T> 等于
  • template<class T> bool not_equal_to<T> 不等于
  • template<class T> bool greater<T> 大于
  • template<class T> bool greater_equal<T> 大于等于
  • template<class T> bool less<T> 小于
  • template<class T> bool less_equal<T> 小于等于
void test01() {
	vector<int> v;
	v.push_back(10);
	v.push_back(70);
	v.push_back(30);
	v.push_back(40);
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
	sort(v.begin(), v.end(), greater<int>());
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

逻辑仿函数:

  • template<class T> bool logical_and<T> 与
  • template<class T> bool logical_or<T> 或
  • template<class T> bool logical_not<T> 非
void test01() {
	vector<bool> v;
	v.push_back(true);
	v.push_back(false);
	v.push_back(true);
	v.push_back(false);
	for (vector<bool>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
	vector<bool> c;
	c.resize(v.size());
	transform(v.begin(), v.end(), c.begin(), logical_not<bool>());
	for (vector<bool>::iterator it = c.begin(); it != c.end(); it++) {
		cout << *it << " ";
	}
}

遍历算法

for_each:

  • for_each(iterator beg, iterator end, _func);
void print01(int v) {
	cout << v << " ";
}

class print02 {
public:
	void operator()(int v) {
		cout << v << " ";
	}
};

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	for_each(v.begin(), v.end(), print01);
	cout << endl;
	for_each(v.begin(), v.end(), print02());
}

transform:

拷贝到另一个容器

  • transform(iterator beg1, iterator end1, iterator beg2, _func)
void print01(int v) {
	cout << v << " ";
}

class Transform {
public:
	int operator()(int v) {
		return v;
	}
};

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	for_each(v.begin(), v.end(), print01);
	cout << endl;
	vector<int> c;
	c.resize(v.size());
	transform(v.begin(), v.end(), c.begin(), Transform());
	for_each(c.begin(), c.end(), print01);
	cout << endl;
}

查找算法

函数原型:

  • find(iterator beg, iterator end, value); 查找返回下标
  • find_if(iterator beg, iterator end, _Pred); 条件查找
  • adjacent_find(iterator beg, iterator end); 查找相邻重复元素
  • bool binary_search(iterator beg, iterator end, value); 二分查找
  • count(iterator beg, iterator end, value) 统计元素出现次数
  • count_if(iterator beg, iterator end, _Pred) 条件统计
void MyPrint(vector<int> v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

class GreaterFive {
public:
	int operator()(int v) {
		return v > 5;
	}
};

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
		if (i > 7) {
			v.push_back(7);
			v.push_back(7);
		}
	}
	MyPrint(v);
	vector<int>::iterator it1 = find(v.begin(), v.end(), 9);
	cout << *it1 << endl;
	vector<int>::iterator it2 = find_if(v.begin(), v.end(), GreaterFive());
	cout << *it2 << endl;
	vector<int>::iterator it3 = adjacent_find(v.begin(), v.end());
	cout << *it3 << endl;
	bool ans = binary_search(v.begin(), v.end(), 7);
	cout << ans << endl;
	int res = count(v.begin(), v.end(), 7);
	cout << res << endl;
	int cnt = count_if(v.begin(), v.end(), GreaterFive());
	cout << cnt << endl;
}

排序算法

函数原型:

  • sort(iterator beg, iterator end, _Pred) 排序
  • random_shuffle(iterator beg, iterator end) 随机排序
  • merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest) 合并两个容器 存储到另一个容器
  • reverse(iterator beg, iterator end) 反转
void MyPrint(vector<int> v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

void Print(int v) {
	cout << v << " ";
}

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	MyPrint(v);
	sort(v.begin(), v.end(), MySort());
	MyPrint(v);
	random_shuffle(v.begin(), v.end());
	MyPrint(v);
}

void test02() {
	vector<int> v, c;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
		c.push_back(i + 10);
	}
	vector<int> target;
	target.resize(v.size() + c.size());
	merge(v.begin(), v.end(), c.begin(), c.end(), target.begin());
	for_each(target.begin(), target.end(), Print);
	cout << endl;
	reverse(target.begin(), target.end());
	MyPrint(target);
}

拷贝替换算法

函数原型:

  • copy(iterator beg, iterator end, iterator dest) 拷贝到另一个容器
  • replace(iterator beg, iterator end, oldvalue, newvalue) 指定范围内更换元素
  • replace(iterator beg, iterator end, _pred, newvalue) 条件替换
  • swap(container c1, container c2) 互换两个容器的元素
void MyPrint(vector<int> v) {
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

void Print(int v) {
	cout << v << " ";
}

class MyWeici {
public:
	int operator()(int v1) {
		return v1 > 5;
	}
};

void test02() {
	vector<int> v, c;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	MyPrint(v);
	vector<int> target;
	target.resize(v.size());
	copy(v.begin(), v.end(), target.begin());
	MyPrint(target);
	replace(target.begin(), target.end(), 6, 99);
	MyPrint(target);
	replace_if(target.begin(), target.end(), MyWeici(), 99);
	MyPrint(target);
	swap(v, target);
	MyPrint(v);
	MyPrint(target);
}

算术生成算法

函数原型:

  • accumulate(iterator beg, iterator end, value) 计算容器元素和
  • fill(iterator beg, iterator end, value) 向容器中填充指定元素
void test02() {
	vector<int> v, c;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	MyPrint(v);
	int sum = accumulate(v.begin(), v.end(), 0);
	cout << sum << endl;
	c.resize(20);
	fill(c.begin(), c.end(), 100);
	MyPrint(c);
}

集合算法

函数原型:

  • set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest) 交集
  • set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest) 并集
  • set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest) 差集
void test02() {
	vector<int> v, c;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
		c.push_back(i + 5);
	}
	MyPrint(v);
	MyPrint(c);
	vector<int> target;
	//target.resize(min(v.size(), c.size()));
	//set_intersection(v.begin(), v.end(), c.begin(), c.end(), target.begin());
	//target.resize(v.size() + c.size());
	//set_union(v.begin(), v.end(), c.begin(), c.end(), target.begin());
	target.resize(max(v.size(), c.size()));
	set_difference(v.begin(), v.end(), c.begin(), c.end(), target.begin());
	MyPrint(target);
}
AMD机密计算虚拟机介绍 阅读详情

相关推荐

从学生项目到工程实践:手把手教你用ATE测试电源芯片的Rdson与漏电流

本文详细介绍了如何将学术级的电源芯片测试方案转化为工业级解决方案,重点讲解使用ATE设备测试Rdson(导通电阻)和漏电流的关键技术。从设备选型、测试夹具设计到量产环境下的工程化实现,提供了实用的优化技巧和常见问题解决方案,帮助工程师提升测试效率和精度。

weixin_42525289的博客 180

C++笔记(提高)(基于黑马程序员)(无代码)

Cpp笔记,提高部分内容。 基于黑马程序员视频+笔记+Gemini制作。 无代码,如需代码参考黑马程序员笔记内容。

m0_64966450的博客 1159

保姆级教程:用STM32CubeMX给STM32F407配置RTC秒中断,并解决掉电时间丢失问题

本文详细介绍了如何使用STM32CubeMX为STM32F407配置RTC秒中断,并解决掉电时间丢失问题。通过硬件原理与软件配置的双视角解析,帮助开发者实现精确计时与时间持久化,适用于物联网设备和工业控制器等场景。

weixin_42519733的博客 136

C++提高编程(黑马程序员笔记)

本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用 1 模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性 例如生活中的模板 一寸照片模板: PPT模板: 模板的特点: 模板不可以直接使用,它只是一个框架 模板的通用并不是万能的 1.2 函数模板 C++另一种编程思想称为 泛型编程 ,主要利用的技术就是模板 C++提供两种模板机制:函数模板和类模板 1.2.1 函数模板语法 函数模板作用: 建立一个通用函数,其函数返回值类型和形参类型可以不具体.

念去去 2386

别再踩坑了!Vue3 + Vant 手把手教你搞定飞书网页应用免登(SSO),附完整代码和重定向URL配置

本文详细介绍了如何使用Vue3和Vant实现飞书H5应用的免登(SSO)功能,包括飞书后台配置的关键细节、Vue3前端实现的最佳实践以及常见问题排查指南。特别针对重定向URL配置、安全设置和错误处理等常见陷阱提供了解决方案,并附有完整代码示例和性能优化建议。

weixin_29323551的博客 404

基于Matlab的自动泊车系统开发:利用模糊控制实现智能停车解决方案的详细教程

Matlab是一种广泛应用于科学计算、工程建模与仿真的编程语言,其强大的工具箱和简洁的编程语法,使其成为开发自动泊车系统的理想选择。在开始编写代码之前,我们需要搭建Matlab的工作环境,并熟悉相关的工具箱,如Fuzzy Logic Toolbox,用于实现模糊控制。首先,确保你已经安装了Matlab软件,并加载了必要的工具箱。接下来,我们将逐步讲解如何在Matlab中实现自动泊车系统。

qq_38334677的博客 663

《黑马笔记》 --- C++ 提高编程

本阶段主要针对C++泛型编程>和STL技术的讲解。

layfolk的博客 1514

西门子G120变频器在立体仓库堆垛机应用参数设置

本文详细介绍了G120 CU240E及CU250S变频器的参数设置流程。主要内容包括:1)快速调试步骤,从新建项目、扫描节点到设置电机类型、负载类型等参数;2)抱闸参数设置方法;3)参数下载异常时的处理方案。重点说明了通过STARTER软件进行向导式调试的完整过程,包括电机铭牌参数输入、识别方式选择等关键环节,并提示了通讯连接注意事项。当下载失败时,提供了通过导入导出项目文件解决问题的具体方法。

xdpcxq的专栏 863

黑马程序员C++提高编程学习笔记

黑马程序员C++提高编程 提高阶段主要针对泛型编程和STL技术 文章目录黑马程序员C++提高编程一、模板1.1 函数模板1.1.1 函数模板基础知识案例一: 数组排序1.2.1 普通函数与函数模板1.2.2 函数模板的局限性1.2 类模板1.2.1 类模板的基础知识1.2.2 类模板与函数模板1.2.3 类模板中的成员函数创建时机1.2.4 类模板成员函数类外实现1.2.5 类模板的对象做函数参数1.2.6 类模板与继承1.2.7 类模板分文件编写1.2.8 类模板与友元案例二: 通用的数组类二、STL

m0_74795952的博客 1348

YOLOv8 PCB缺陷检测系统全流程实战:从开发到UI展示详解

毕设路上难免有波折,但只要跟着这个教程把“数据集处理、模型训练、UI开发”每一步都落实,你就已经超越了大多数同学。这个“PCB缺陷检测系统”既有技术深度(YOLOv8是工业级主流算法),又有工程价值(解决电子制造的实际痛点),还具备出色的可视化展示——这样的毕设,拿高分是水到渠成的事。

FJN110的博客 214

PCL 提取两片点云的非重叠部分【2025最新版】

PCL 提取两片点云的非重叠部分。博客长期更新,本文最近一次更新时间为:2025年9月1日。

点云侠的博客 36万+

【C++】黑马程序员-C++提高编程学习笔记

根据黑马程序员C++课程内容,结合讲义,将自己学习C++的过程中将自己觉得有必要记下的笔记进行整理,方便复习回顾,编程环境为VisualStudio。本阶段主要对泛型编程和STL技术做详细讲解,探讨C++更深层的使用。模板就是建立通用的模具,大大提高复用性。模板的特点:函数模板作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。 解释:template — 声明创建模板typename — 表面其后面的符号是一种数据类型,可以用class代替T — 通用的数据类型,名称

qq_62361050的博客 1321

【路径规划】Theta_star算法机器人栅格地图最短路径规划【含Matlab源码 2618期】

Theta_star算法机器人栅格地图最短路径规划 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 362

黑马程序员匠心之作 || C++提高编程笔记

学习目标:vector中存放自定义数据类型,并打印输出//vector容器存放自定义数据类型#include //标准算法头文件public:int m_Age;//向容器中添加数据//遍历数组it!= v.end();it++)//向容器中添加数据//遍历数组it!= v.end();test02();return 0;

强哥的微博 1516

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

黑马C++学习笔记——C++编程提高

1.模板 2. STL概念 3.string容器 4.vector容器 5.deqeue容器 6. list容器 7. set容器 8. map容器 9. STL——函数对象 10 STL常用算法

m0_49687898的博客 396

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

10 黑马笔记之C++提高编程语法-泛型编程与STL

月薪过万第一步,先当黑马程序员,本章记录C++语法之文件操作易遗忘的点

qq_54412097的博客 1842

黑马程序员学习笔记-------c++提高编程

c++提高编程 本阶段主要针对c++泛型编程和STL技术做详细讲解,探讨cpp更深层的使用 1 模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性 模板的特点: 模板不可以直接使用,它只是一个框架 模板的通用并不是万能的 1.2 函数模板 c++另一种编程思想称为 泛型编程 ,主要利用的技术就是模板 c++提供两种模板机制:函数模板和类模板 1.2.1 函数模板语法 函数模板作用: 建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。 语法:

qq_36421001的博客 3586

C++提高编程(模板、STL函数,黑马程序员笔记)

模板函数,stl函数初认识

weixin_63003502的博客 872

【C++】黑马程序员 | c++教程从0到1入门编程笔记 | c++提高编程

配套视频:https://www.bilibili.com/video/BV1et411b73Z 1 模板 本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性 模板的特点: 模板不可以直接使用,它只是一个框架 模板的通用并不是万能的 1.2 函数模板 C++另一种编程思想称为泛型编程 ,主要利用的技术就是模板 C++提供两种模板机制:函数模板和类模板 1.2.1 函数模板语法 函数模板作用:建立一个通用函数,其函

qq_38939822的博客 2910

C++ 黑马程序员-笔记(C++提高编程)

本阶段主要针对 C++泛型编程和STL技术做详细讲解,探讨 C++更深层的使用。 一、模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性。 模板的特点: 模板不可以直接使用,它只是一个框架 模板的通用并不是万能的 1.2函数模板 C++另一种编程思想称为 泛型编程 ,主要利用的技术就是模板 C++提供两种模板机制:函数模板和类模板 1.2.1 函数模板语法 函数模板作用: 建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。 语法: te

m0_49734843的博客 736

B站黑马c++学习笔记 —— 提高编程篇

大纲1 模板1.1 模板的概念1.2 函数的模板1.2.1 是1.3 类模板1.3.1 是2 STL初识3 STL-常用容器4 STL-函数对象5 STL-常用算法 1 模板 1.1 模板的概念 1.2 函数的模板 1.2.1 是 1.3 类模板 1.3.1 是 2 STL初识 3 STL-常用容器 4 STL-函数对象 5 STL-常用算法 ...

qq_52382976的博客 2295

黑马C++笔记 提高编程篇(1)

从而在调用模板成员函数时完成实例化,生成对应的二进制代码。

2403_89908394的博客 708

笔记 黑马程序员C++教程从0到1入门编程——提高编程02

3 STL-常用容器 string容器 189 构造函数 string s1;//创建一个空的字符串 默认构造 const char *str = "hello"; string s2(str);//使用字符串S初始化 cout << "s2=" << s2 << endl; //s2 = hello string s3(s2);//使用一个string对象初始化另一个string对象 cout << "s3=" << ..

m0_58125693的博客 2036

笔记 黑马程序员C++教程从0到1入门编程——提高编程01

主要针对C++泛型编程和STL技术做详细讲解 1 模板 01 模板的概念 模板就是建立通用的模具,大大提高复用性 特点:不可以直接使用,只是一个框架;通用并不是万能的 02 函数模板基本语法 目的是为了提高函数复用性,函数模板将类型参数化 03 函数模板注意事项 自动类型推导,必须推导出已知的数据类型T,才可以使用 模板必须要确定出T的数据类型,才可以使用 04 函数模板案例-数组排序 //实现通用 对数组进行排序的函数 template <class T&g...

m0_58125693的博客 1564

笔记 黑马程序员C++教程从0到1入门编程——提高编程03

4 STL-函数对象 237 函数对象 谓词 238 一元谓词 239 二元谓词 内建函数对象 240 算术仿函数 241 关系仿函数 242 逻辑仿函数 5 STL-常用算法

m0_58125693的博客 1324

《黑马》——C++

C++教程视频 1.黑马程序员 参考笔记 ----基础入门篇---- 入门到结构体 ----核心编程篇---- 类和对象 ----编程提高篇---- STL

qq_43693804的博客 219

【C++学习】核心编程之内存分区模型、引用和函数提高(黑马学习笔记)

目录一、内存分区模型1.1程序运行前1.2程序运行后1.3new操作符二、引用2.1基本使用2.2引用做函数参数2.3引用做函数返回值2.4引用的本质2.5常量引用 三、函数提高3.1函数默认参数3.2函数占位参数3.3函数重载系列文章:一、内存分区模型C++程序在执行时,将内存大方向划分为4个区域代码区:存放函数体的二进制代码,由操作系统进行管理的全局区:存放全局变量和静态变量以及常量栈区:由编译器自动分配释放, 存放函数的参数值,局部变量等堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回

学习中 1122
上一篇: C++核心编程(黑马笔记)
下一篇: C++基础入门(省略版本)(黑马笔记)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值