第一次小考核总结

1、debug和Release的区别

Debug:调试版本,包含调试信息,所以容量比Release大,不对程序进行优化,会生成.exe和.dll文件,还有.pdb文件(记录中断调试信息)
Release:发布版本,编译时对应用程序进行优化,以便用户很好使用

2、内存分配的方式—静态内存、栈内存、堆内存

从静态存储区分配:编译时分配,程序运行时都存在,全局变量,static变量、常量在这里存储
在栈区分配:代码执行时创建,执行结束自动释放。栈内存分配运算内置于处理器,效率高,容量有限
在堆区分配:动态分配内存。程序员自己new和delete,使用灵活,如果不回收,运行会出现内存泄漏,频繁分配和释放不同大小的堆空间会产生堆内碎块。

3、C++中堆(heap)和栈(stack)的区别

在C++中,内存分为五区:堆,栈,自由存储区、全局/静态存储区、常量存储区。
:编译器在需要时自动分配,不需要时自动清除,存放局部变量、函数参数
:new分配的内存快,由程序员自动释放(编译器不管),如果程序员不释放,资源将在操作系统结束后自动回收(Java自动回收机制)。
自由存储区:malloc分配的内存块,free来释放,和堆相似
全局/静态存储区:存放全局变量和静态变量
常量存储区:存放常量,不允许修改。
自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆

管理方式 堆中资源由程序员控制 栈资源由编译器自动管理,无需手工控制
内存管理机制 系统有一个记录空闲内存地址的链表,当系统收到程序申请时,遍历该链表,寻找第一个空间大于申请空间的堆结点,删除空闲结点链表中的该结点,并将该结点空间分配给程序 只要栈的剩余空间大于所申请空间,系统为程序提供内存,否则报异常提示栈出
空间大小 堆是不连续的内存区域(系统是用链表来存储空闲内存地址,不是连续的),堆大小受限于计算机系统中有效的虚拟内存(32bit 系统理论上是4G),堆的空间比较灵活,比较大 栈是一块连续的内存区域,大小是操作系统预定好的
碎片 对于堆,频繁的new/delete会造成大量碎片,使程序效率降低 对于栈,它是一个先进后出的队列,进出一一对应,不会产生碎片。
生长方向 堆向上,向高地址方向增长。 栈向下,向低地址方向增长。
分配方式 堆都是动态分配 栈有静态分配和动态分配,静态分配由编译器完成(如局部变量分配)

4、C++多线程

线程:是操作系统能够进行CPU调度的最小单位。
多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程基于线程
基于进程的多任务处理是程序的并发执行。
基于线程的多任务处理是同一程序片断的并发执行。

多线程并发:即多个线程同时执行,把一个任务拆分多个任务,然后由不同线程处理不同子任务,使得多个子任务同时进行。
同步:在发出调用时,没得到结果前,该调用不返回;
异步:调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。
类似于银行一个柜台和多个柜台。

小笔记:
需要包含头文件 #include
std::thread 默认构造函数,创建一个空的 std::thread 执行对象。
可以是 函数指针、函数对象、lambda表达式
【C++】Sleep函数的用法
功能:执行挂起一段时间,等待一段时间在继续运行
需要引用头文件:#include

案例1:
#include
#include//声明管理线程的函数和类

//一个虚函数
void foo(int z)
{
	for (int i = 0; i < z; i++)
	{
		std::cout << "线程使用函数指针作为可调用参数" << std::endl;
	}
}

class thread_obj
{
public:
	void operator()(int x)//重载()运算符
	{
		for (int i = 0; i < x; i++)
		{
			std::cout << "线程使用函数对象作为可调用参数" << std::endl;
		}
	}
};

int main()
{
	std::cout << "线程1、2、3独立运行" << std::endl;
	//函数指针
	 std::thread th1(foo,3);//创建一个名为th1的线程

	 //函数对象
	 std::thread th2(thread_obj(), 3);

	 //lambda表达式
	 auto f=[](int x)
	 {
		 for (int i = 0; i < x; i++)
		 {
			 std::cout << "线程使用lambda表达式作为可调用参数" << std::endl;
		 }
	 };
	 std::thread th3(f, 3);
	 th1.join();
	 th2.join();
	 th3.join();
	system("pause");
	return 0;
}

输出:

线程1、2、3独立运行
线程使用lambda表达式作为可调用参数
线程使用lambda表达式作为可调用参数
线程使用lambda表达式作为可调用参数
线程使用函数对象作为可调用参数
线程使用函数对象作为可调用参数
线程使用函数对象作为可调用参数
线程使用函数指针作为可调用参数
线程使用函数指针作为可调用参数
线程使用函数指针作为可调用参数

案例2:请用异步线程实现每隔100ms输出10到0

小笔记:
join()函数
th1调用了join函数,所以必须等到th1完成,th1.join()才能返回
需要包含头文件:#include

#include
//线程函数
int  thread_fun(int x)
{
	for (int i = x; i >=0; i-=2)
	{
		std::cout << "子线程:i=" << i << std::endl;
		Sleep(100);
	}
	return 0;
}

int main()
{
	std::thread th1(thread_fun, 10);//创建线程
	//主线程
	for (int i = 9; i >= 0; i-=2)
	{
		std::cout << "主线程:i=" <<i << std::endl;
		Sleep(100);
	}
	th1.join();//join()函数写在这里输出是随机的
	return 0;
}

输出:每次结果不一样

主线程:i=9
子线程:i=10
主线程:i=7
子线程:i=8
主线程:i=5
子线程:i=6
主线程:i=3
子线程:i=4
子线程:i=2
主线程:i=1
子线程:i=0

5、Opencv Mat的使用

Mat是一种图像容器,是二维向量,灰度图的Mat一般存放< uchar >类型,RGB彩色图像一般存放< Vec3b > 类型。

6、三维向量的叉乘

三维向量ijk叉乘
| i j k |

| a1 b1 c1 |

| a2 b2 c2 |

=(b1c2-b2c1,c1a2-a1c2,a1b2-a2b1)

7、对于n * n型矩阵,求它的逆矩阵;对于n * m(n!=m)型矩阵,求它的伪逆矩阵

其他详见笔记本7月21日笔记

矩阵的逆

n阶矩阵A和B,AB=BA=。我们称B是A的逆矩阵,而A则被称为可逆矩阵。其中E为单位矩阵,也叫对角线矩阵。
可逆条件:|A|!=0
奇异矩阵:不可逆的矩阵。
非奇异矩阵:可逆的矩阵。
正交矩阵:ATA=E,正交矩阵的逆等于它的转置矩阵;

  1. 伴随矩阵法
  • 伴随矩阵的求法
  • 对于二阶矩阵,它的伴随矩阵只需要将主对角线元素位置互换,次对角线元素符号交换
  • 余子式:伴随矩阵的每个元素的余子式是除去当前元素行和列,剩下的元素构成的行列式
  • 代数余子式:取行列式的值,符号为当前行标和列表(-1)^i+j;
  1. 初等变换法
    增广矩阵:在矩阵的右侧放置一个同阶的单位矩阵

  2. 待定系数法
    解方程组

矩阵的伪逆

8、共享指针和普通指针

智能指针会在超出作用域后自行清理(从而消除对大多数内存泄漏的恐惧)。
共享指针是一种智能指针,它会对存在的指针实例数进行计数,并且仅在计数达到零时才清理内存。
与普通指针相比,共享指针重载了*、->、和==运算符;

8.1shared_ptr原理

不同的shared_ptr对象可以与相同的指针相关联,在内部使用引用奇数机制来实现这一点,每个对象在内部指向两个位置。

  1. 指向对象指针
  2. 用于控制引用计数数据的指针
    1、当新的 shared_ptr 对象与原共享指针关联时,则在其构造函数中,将与此指针关联的引用计数增加1。
    2、当任何与之相关的shared_ptr 对象被析构时,例如局部函数调用结束,则在其析构函数中,它将关联指针的引用计数减1。如果引用计数变为0,则表示没有其他 shared_ptr 对象与此内存关联,在这种情况下,它使用delete函数删除堆中对应内存。

检查 shared_ptr 对象的引用计数
ptr.use_count();
所在库:#include < memory > 或者**#include< boost/shared_ptr.hpp>**

8.2 shared_ptr 对象的构造

  1. 使用空参数构造函数

std::shared_ptr< Student >stu_ptr;//stu_ptr相当于一个NULL指针,做*ptr或者ptr->XX会出现异常

  1. 从new操作符的返回值构造

std::shared_ptr< Student > stu_ptr(new Student());
//使用std::make_shared类模板
std::shared_ptr stu_ptr2 = std::make_shared();

  1. 使用复制构造函数或者等号重载

std::shared_ptr< Student>stu_ptr3(stu_ptr);

7.3shared_ptr赋值

当共享指针 a 被赋值成 b 的时候,如果 a 原来是 NULL, 那么直接让 a 等于 b 并且让它们指向的东西的引用计数加 1; 如果 a 原来也指向某些东西的时候,如果 a 被赋值成 b, 那么原来 a 指向的东西的引用计数被减 1, 而新指向的对象的引用计数加 1。

std::shared_ptr< Student > stu_ptr(new Student());
std::shared_ptr< Student > stu_ptr4(new Student());
stu_ptr = stu_ptr4;//stu_ptr原先所指向的对象会被销毁,stu_ptr4所指对象引用计数+1

shared_ptr 的对象在构造之后,可以被赋予空值,此时使用的应该是 reset() 函数或者nullptr。

stu_ptr4.reset();//stu_ptr4 原先所指的对象的引用计数-1,并且 stu_ptr4 会变成 NULL。这里内存会被销毁
stu_ptr4 = nullptr;

7.4shared_ptr类型转换

shared_ptr 有两种类型转换的函数,一个是 static_pointer_cast, 一个是 dynamic_pointer_cast。

std::shared_ptr<A> ptra;
std::shared_ptr<B> ptrb(new B());
ptra = dynamic_pointer_cast<A>(ptrb);

7.4shared_ptr其他用法!!!!

  • 共享指针的重置
std::shared_ptr<T> ptr(new T());
ptr.reset(new T()); // 原来所指的对象会被销毁
  • NULL检测
    shared_ptr 对象而不分配任何值时,它就是空的,即地址为000000000;普通指针不分配空间的时候相当于一个野指针,指向垃圾空间,且无法判断指向的是否是有用数据。
if(!ptr3)
    std::cout<<"Yes, ptr3 is empty" << std::endl;
if(ptr3 == NULL)
    std::cout<<"ptr3 is empty" << std::endl;
if(ptr3 == nullptr)
    std::cout<<"ptr3 is empty" << std::endl;

if(ptr3==0)

    std::cout<<"ptr3 is empty" << std::endl;

9、C++ lambda表达式

lambda表达式定义了一个匿名函数

语法:[ capture ] (params) opt->ret{ body;}; [捕获列表](参数表)
函数选项->返回值类型{函数体;}
auto f =[ ] (int a)->int{return a+1;}

auto f=[](int x)//C++11 中允许省略 lambda 表达式的返回值定义
	 {
		 for (int i = 0; i < x; i++)
		 {
			 std::cout << "线程使用lambda表达式作为可调用参数" << std::endl;
		 }
	 };

lambda 表达式在没有参数列表时,参数列表是可以省略的

auto f1 = [](){ return 1; };
auto f1 = []{ return 1; };//省略空参数表

lambda 表达式捕获列表

  • [] 不捕获任何变量。
  • [&] 捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。
  • [=] 捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。
  • [=,&foo] 按值捕获外部作用域中所有变量,并按引用捕获 foo 变量。
  • [bar] 按值捕获 bar 变量,同时不捕获其他变量。
  • [this] 捕获当前类中的 this 指针,让 lambda 表达式拥有和当前类成员函数同样的访问权限。如果已经使用了 & 或者 =,就默认添加此选项。捕获 this 的目的是可以在 lamda 中使用当前类的成员函数和成员变量。

10、C++ atoi()使用

atoi()函数将数字格式的字符串转换为整数类型。例如,将字符串“12345”转换成数字12345。

你可能感兴趣的:(学习,c++,线性代数)