【C++】入门

news2024/12/28 2:02:37

目录

  • 1. 什么是C++
  • 2. 命名空间
    • 2.1 命名空间的定义
    • 2.2 命名空间的使用
  • 3. 输入和输出
  • 4. 缺省参数
    • 4.1 概念
    • 4.2 分类
  • 5. 函数重载
    • 5.1 函数重载概念
    • 5.2 为什么支持函数重载
  • 6. 引用
    • 6.1 概念
    • 6.2 特性
    • 6.3 常引用
    • 6.4 指针与引用的区别
  • 7. 内联函数
    • 7.1 特性

1. 什么是C++

C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机,
20世纪80年代,计算机界提出了OOP(object oriented
programming:面向对象)思想,支持面向对象的程序设计语言应运而生。 1982年,Bjarne
Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。因此:C++是基于C语言而产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。

简言之C++是由C语言发展而来,弥补和扩展了C语言中不足的设计和功能。

2. 命名空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
在C语言中,当一个全局变量的变量名与其它变量的变量名或者函数名发生冲突时,这种情况是C语言除了更改它们的名字之外没有其它处理方法了。

#include <stdio.h> 
#include <stdlib.h> 
int rand = 10; 

int main() 
{ 
    printf("%d\n", rand); 
    return 0; 
} 
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”

因此c++为了解决上述情况,便引入命名空间的概念。

C++官方定义的命名空间为:std
C++标准库中的函数或者对象都是在命名空间std中定义的,所以要使用标准函数库中的函数或对象都要使用std来限定。

2.1 命名空间的定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{} 中即为命名空间的成员。

//pri是命名空间的名字,一般开发中是用项目名字做命名空间名。
//1. 正常的命名空间定义
namespace pri
{
	// 命名空间中可以定义变量/函数/类型
    int rand = 10;
    int x = 20;
	//...
	int Add(int left, int right)
    {
    	return left + right;
    }
	struct Node
    {
        struct Node* next;
    	int val;
	};
}
//2. 命名空间可以嵌套
namespace N1
{
    int a;
    int b;
    int Add(int left, int right)
    {
         return left + right;
    }
    namespace N2
    {
        int c;
        int d;
        int Sub(int left, int right)
        {
            return left - right;
        }
    }
}
//3. 同一个工程中允许存在多个相同名称的命名空间
//编译器最后会合成同一个命名空间中。
namespace N1
{
    int Mul(int left, int right)
    {     
        return left * right;
    }
}
namespace N1
{
    int Add(int left, int right)
    {     
        return left + right;
    }
}
//会将两个N1合成一个

注意:一个命名空间就定义了一个新的作用域,也叫做命名空间域,命名空间中的所有内容都局限于该命名空间。

这里有个问题,域中的变量是局部还是全局变量?
其实域中定义的变量是全局变量,与普通的全局变量没有什么区别,但是会影响编译器的查找规则。
编译器的默认查找规则是:在查找该变量时首先会在局部域中寻找(函数内部),若找不到在去全局域中去找,还找不到直接报错,它并不会在去命名空间中去找。
那么如果就是想访问命名空间中的内容时该怎么做呢?

2.2 命名空间的使用

接下来简单介绍几种访问命名空间中成员的方法:

#include <iostream>
namespace pri
{
    int g_val = 10;
	//...
}

第一种访问命名空间做法:

int main()
{
    //名称pri + 域作用限定符::
    printf("%d\n", pri::g_val);
    return 0;    
}

这种写法是以指定的方式直接去访问命名空间中的成员,若找不到也不会去局部或者全局区去找,直接报错。因此即使不同的命名空间域中出现了相同的成员时,使用各自的名称+域作用限定符即可访问各自的空间中的成员,不会出现冲突。

但是这种要求指定的写法每次都要写上空间名称+域作用限定符才能访问其中的成员,那么有没有一种简单的写法呢?

第二种访问命名空间做法,展开命名空间:

//使用如下写法后续即可直接访问空间中的成员
using namespace pri
//展开命名空间
int main()
{
    printf("%d\n", g_val);
    return 0;    
}

命名空间就好比一堵围墙,把其中的成员封装起来与外界进行隔离,使用特定的方式才能访问其中的成员,以达到解决命名冲突的问题。

而上面这种做法就相当于把这堵墙给拆了,谁都可以直接进行访问也比较方便,但是这种做法又会出现最开始的问题,出现命名冲突。

有没有一种方法即能方便的使用又能不展开命名空间的方法呢?

第三种访问命名空间做法,指定部分展开:

//将最常用的部分成员展开
//比如官方定义的空间std中的输出函数cout
//换行字符endl
using std::cout;
using std::endl;

//自己定义空间中的常用成员
using pri::g_val;
int main()
{
    printf("%d\n", g_val);
    cout << g_val << endl;
    //不展开写法:
    //std::cout << pri::g_val << std::endl;
    return 0;    
}

这种写法很好的解决了即能方便的使用部分成员又能不展开全部的命名空间,但需要注意的是要避免自己定义的与常用重名即可。

3. 输入和输出

#include<iostream>
using namespace std;

int main()
{
	int a;
	char b;
    //这里的cin和cin分别是C++中的对象
    //负责输入和输出

    //会自动识别类型
	cin >> a >> b;
	cout << a << ' ' << b << endl;
	return 0;
}
  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含头文件中。
  3. <<是流插入运算符,>>是流提取运算符。
  4. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识后续才会学习,所以这里只是简单学习它们的使用。后面还有一个章节更深入的学习IO流用法及原理。

和C中的输入输出函数相比各有各的优势,建议是根据场景,哪个好用用哪个。

4. 缺省参数

4.1 概念

缺省 = 默认,含义相同

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

//不传参数默认a=0
void Func(int a = 0)
{
	cout << a << endl;
}
int main()
{
    // 没有传参时,使用参数的默认值,输出0
    Func();     
    // 传参时,使用指定的实参,输出10
    Func(10);   
    return 0;
}

如果函数带参数且不使用缺省值,调用时不传参数会直接报错。

4.2 分类

  • 全缺省参数
void func(int a = 10, int b = 20, int c = 30)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}
int main()
{
	func();
	func(a);
	func(a, b);
	func(a, b, c);
	return 0;
}

上面几种调用方式都是正确的,但需要注意的是传入的参数与形参是从左到右依次匹配的,不可以跳着传参。

错误调用方式:

func(a, ,c);
func(, b, c);
  • 半(部分)缺省参数
void func(int a, int b = 10, int c = 20)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}
int main()
{
	func(a);
	func(a, b);
	func(a, b, c);
	return 0;
}

至少要传入一个参数,同时也是从左到右依次匹配。

错误调用方式:

func();
func(a, ,c);
func(, b, c);

关于半缺省还要几点需要注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现,同时出现会出现二义性,一般要在声明中给出。
  3. 缺省值必须是常量或者全局变量
  4. C语言不支持(编译器不支持)

5. 函数重载

自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。
比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个是男足。前者是“谁也赢不了!”,后者是“谁也赢不了!

5.1 函数重载概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似但数据类型不同的问题,比如:

#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
	cout << "int Add(int left, int right)" << endl;
	return left + right;
}
double Add(double left, double right)
{
	cout << "double Add(double left, double right)" << endl;
	return left + right;
}

// 2、参数个数不同
void f()
{
	cout << "f()" << endl;
}
void f(int a)
{
	cout << "f(int a)" << endl;
}

// 3、参数类型顺序不同
void f(int a, char b)
{
	cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
	cout << "f(char b, int a)" << endl;
}

int main()
{
	Add(10, 20);
	Add(10.1, 20.2);
	f();
	f(10);
	f(10, 'a');
	f('a', 10);
	return 0;
}

以下代码也构成函数重载,因为参数个数不同,但是有什么问题?

#include <iostream>
using namespace std;
void func(int a = 0)
{
	cout << "func(a)" << endl;
}
void func()
{
	cout << "func(NULL)" << endl;
}
int main()
{
	func();
	return 0;
}

这种调用方式会出现问题,因为全缺省参数调用时也可以不用传参,因此就会和无参的函数引起冲突,即出现二义性,使得函数调用不明确。

  • 返回值不同构不构成函数重载?

答案是不构成,因为在调用时编译器无法确定返回值类型,进而无法分辨出是要调用哪个函数。这样便出现了二义性,所以不构成函数重载。

5.2 为什么支持函数重载

C++对于函数重载是支持的但是C语言却不支持是为什么?

简单的说是:C语言源程序在编译期间生成符号表时,函数是直接用它的函数名+地址的形式形成的符号表,没有任何的修饰。相同的函数会形成相同的符号和地址,但是符号表中的符号都是只存在一个,因此会编译错误,所以C语言不支持函数重载。

而C++则使用了不同的策略,C++源程序在编译形成符号表的时候,函数的符号表并不是单单地将函数名作为符号,而是使用了某种规则,这个规则叫做函数名修饰规则。
将它的参数(个数或类型或类型顺序)信息也加入到了符号中,因此相同的函数名有着不同的参数时经过修饰后最终得到的符号是不同的,不同的符号会配上不同的地址,所以后续进行链接时会根据调用的函数的参数(个数或类型或类型顺序)信息,去符号表里就能找到对应地址处的函数。这也就是为什么C++支持函数重载。

其实在编译器的角度,编译时就已经把它们当作不同的函数来看待了。

6. 引用

6.1 概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,在语法层面编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间,但是在编译器层面是要开辟空间的。

比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。

示例:

int main()
{
	int a = 10;
    //类型& 引用变量名(对象名) = 引用实体;
	int& ra = a;
    //结果相同
    printf("%p\n", &a);
    printf("%p\n", &ra);
	return 0;
}

此时的ra与a一起表示一块存储空间,修改其中一个另一个也会发生变化,和指针有些许类似。别名也可以有很多个。

有了引用后,有些方面就会比指针更方便,比如交换两个数据:

void swap(int& x, int& y)
{
	int tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	swap(a, b);
 	return 0;
}

x是a的别名,y是b的别名,交换x和y就是交换a和b。比传地址方便多了,这是引用的一个便捷之处。

6.2 特性

  1. 引用在定义时必须初始化。
//错误示例
int main()
{
    //error
	int& ra;//必须初始化,也就是必须要说明你是谁的引用
	return 0;
}
  1. 一个变量可以有多个引用。
int main()
{
	int a = 10;
	int& ra = a;
	int& rra = ra;
	return 0;
}
  1. 用一旦引用一个实体,再不能引用其他实体。
int main()
{
	int a = 10;
	int& ra = a;
	int b = 20;
	ra = b;
    //注意上面一条语句的含义是把b的值赋给ra也就是a
    //并不是让ra重新引用作为b的别名
    //也就是说一旦引用了一个实体,就无法在引用其它实体
	return 0;
}

6.3 常引用

void TestConstRef()
{
    int a = 10;    
    //这里定义的a可读可写
    int& ra = a;   
    //正确,这种写法属于权限不变,也可读可写
    const int& rra = a;
    //正确,这种写法属于权限缩小,可读不可写
	
    const int b = 10;
    //这里定义的b可读不可写
    int& rb = b; 
    //报错,这种写法属于权限放大,可读可写
    const int& rrb = b;
    //正确,这种写法属于权限不变,也可读不可写
}

当const修饰一个引用或者指针时,对于引用或者指向对象的读写权限,只可不变或者缩小,绝不可方放大。

int cnt()
{
	int x = 10;
    return x;
}
int main()
{
	double d = 12.34;
    int& rd = d; 
    //该语句编译时会出错,类型不同
    //当类型不同时会发生隐式类型转换,转换的过程中会发生临时拷贝
    //因此本质rd是引用的是这个拷贝的临时变量
    //而临时变量具有长属性,所以前面要加上const修饰

    int& ret = fun();
    //这种写法也是错误的
    //因为接收的返回值并不是x,而是x的拷贝
    //将x的值拷贝到一个临时变量中返回由ret来接收
    //又因为临时变量具有长属性
    //所以前面也需要加const修饰
    return 0;
}

6.4 指针与引用的区别

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址所占字节个数(32位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

7. 内联函数

根据之前对栈帧的理解,调用函数是有成本的,体现在时间和空间上,具体是栈帧的形成和释放有成本。
对于某些需要频繁调用的函数,也就意味着需要不断地开辟和释放栈帧,这样对于程序的效率是非常不利的。

因此为了提高运行效率,对于此类频繁调用的函数C语言的做法是使用宏函数来代替,因为宏在预处理时就在它所在的位置替换成它的宏体代码,并不会开辟栈帧空间。这种做法有效的提高了效率,但是宏本身是有一些缺陷的,比如:

  • 宏体无法调试
  • 宏直接进行替换,并不会进行类型检查
  • 容易写错,尤其是优先级问题
  • 等等…

而在C++中为了对解决上面提到的一些缺陷,便提出了一个新的关键字:inline。
它的作用是:以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率,可以理解为宏的升级版。

语法如下:

//与普通写法没什么区别
//只需要在返回值前加inline即可
inline int Add(int x, int y)
{
	return x + y;
}
int main()
{			
	int ret = Add(1, 3);
	cout << ret << endl;
	return 0;
}

汇编角度下:
在这里插入图片描述
可以发现并没有发生函数调用,直接在寄存器中进行运算,并把结果保存到ret中。

如果不加inline修饰:
在这里插入图片描述
call指令为函数调用,可以发现不加的情况下发生了函数调用开辟栈帧。

7.1 特性

这里思考一个问题,被inline修饰的函数都会展开吗?

答案是并不是,如果只要被inline修饰就会展开的话,就会造成文本代码的篇幅增大,如果调用的地方很多,展开后文件就会变的越大。
所以建议用inline来修饰需要频繁调用的小函数,不能是递归或者大函数,如果是编译器会忽略inline特性。
而且inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,下图为《C++prime》第五版关于inline的建议:
在这里插入图片描述
为什么函数长了以后就不展开了?

原因是函数太长展开后会引起代码膨胀
比如说一个函数编译后有30条指令,而实际调用它的地方有10000处,在每个调用处展开后指令条数为30*10000条。而不展开的话就只有那一份30条的指令,每次调用只是去复用那块代码,因此实际指令数为30+10000条。
又因为编译出来的可执行程序的大小也就是安装包的大小与指令条数是息息相关的,从上面可以得知,展开与不展开后的指令条数相差是非常大的,那也就会导致安装包的大小也会相差的非常大,安装包太大会比较占用存储空间。

内联的一些特性:

  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。
  2. inline不建议声明和定义分离,分离会导致调用时链接错误。因为inline被展开,就没有函数地址了,链接就会找不到,所以建议直接在头文件中或者本文件中定义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/472597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【c语言】五大内存区域 | 堆区详解

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ…

Paimon: Streaming data lake 数据湖项目的后起之秀

什么是Paimon? Paimon的官网介绍是&#xff1a;Streaming data lake platform with high-speed data ingestion, changelog tracking and efficient real-time analytics. Paimon 是流数据湖平台&#xff0c;具有高速数据摄取、变更日志跟踪和高效的实时分析能力 数据湖是大…

unity什么是曲线动画?

介绍 unity什么是曲线动画&#xff1f; 在Unity中&#xff0c;曲线动画&#xff08;Curve Animation&#xff09;是一种基于曲线的动画系统&#xff0c;它允许你通过在时间轴上编辑曲线来控制游戏对象的某个属性在时间上的变化。曲线动画可以用于很多方面&#xff0c;比如控制…

Linux套接字编程-2

在上一篇博客中&#xff0c;我们先对套接字编程的内容进行了一个简单涵盖&#xff0c;并详细陈述了UDP协议内容。本篇我们承接上文&#xff0c;讲述完UDP后&#xff0c;我们来讲解TCP。 目录 1.TCP协议 1.1通信两端流程 1.1.1服务端流程 1.1.2客户端流程 1.2套接字相关操…

LeCun、田渊栋参与撰写,70页「自监督学习」大全

来源 | 机器之心 微信号&#xff1a;almosthuman2014 「关于自监督学习&#xff0c;你想知道但又不敢问的一切都在这里了。」图灵奖得主、Meta 人工智能首席科学家 Yann LeCun 刚刚发了这样一则推文。 在推文中&#xff0c;LeCun 介绍了他和 Meta 人工智能研究院研究员、研究经…

数据结构学习记录——判断是否为同一颗二叉搜索树(题意理解、求解思路、程序搭建框架、具体函数的实现)

目录 题意理解 问题 描述 输入样例 输出样例 求解思路 建两棵二叉树 不建树 建一棵树 搜索树表示 程序框架搭建 如何建搜索树 如何判别 方法 查找函数 判断函数 其他函数 题意理解 给定一个插入序列就可以唯一确定一颗二叉搜索树。 但是&#xff0c;一颗给定…

libigl添加Viewer Menu时出现imgui相关的错误:无法打开包括文件: “imgui.h”: No such file or directory

libigl添加如下图所示的Viewer Menu时&#xff0c;出现了“无法打开包括文件: “imgui.h”: No such file or directory”的错误 很显然是libigl内嵌的imgui出了问题 从项目路径libigl-example-project-main\out\build\x64-Release\_deps\libigl-src\include\igl\opengl\glfw\…

【谷粒商城之CompletableFuture异步编排】

本笔记内容为尚硅谷谷粒商城CompletableFuture异步编排部分 目录 一、线程回顾 1 、初始化线程的 4 种方式 2.、线程池的七大参数 运行流程&#xff1a; 3、常见的4种线程池 4、开发中为什么使用线程池 二、CompletableFuture 异步编排 业务场景 1、创建异步对象 …

无线化超轻薄,香港城市大学体感反馈贴片WeTac

此前&#xff0c;青亭网曾报道香港城市大学与腾讯Robotics X Lab合作研发的低电压体感方案&#xff0c;原理是通过微电流刺激来模拟触觉&#xff0c;可模拟微小物体的体感。近期&#xff0c;香港城市大学的一组科研人员也公布了一项类似的方案&#xff1a;WeTac&#xff0c;该方…

轻松上手:使用VSCode调试Python模块级代码的完整教程

安装VSCode&#xff1a;请确保已经安装了Visual Studio Code。安装Python插件&#xff1a;在VSCode中&#xff0c;转到Extensions视图 (View -> Extensions) 并搜索"Python"。找到由Microsoft提供的插件并点击安装。重启VSCode以确保插件安装正确。准备项目&#…

边听歌边充电LDR6028+LDR9201既能充电又能OTG方案

随着type-c接口的普及&#xff0c;市面上的手机&#xff0c;平板&#xff0c;笔电逐渐都采用了type-c接口&#xff0c;设备为了不断的追求更轻薄的机身和防水要求慢慢的取消了一些影响手机外观完整性的接口&#xff0c;比如3.5mm耳机孔。 有线耳机用户一般会选择使用C口转3.5m…

资深架构师解读零代码开发平台—如何不写代码实现流程审批

审批节点 “审批节点&#xff1a;” 流程中涉及审批时&#xff0c;需要用到审批节点。审批可通过或者驳回&#xff0c;也可以发送通知。可以多人会签/或签审批。 1. 审批节点 1.1 审批设置 ① 审批方式 审批方式默认为或签方式&#xff0c;只一个人审批即可 当选择会签时&#…

【英语】大学英语CET考试,口语考试介绍与备考1(讲义笔记)

文章目录 1、考试基本信息2、考试题型介绍3.1 短文朗读与回答问题&#xff08;语音篇&#xff09;3.1.1 语音篇真题3.1.2 语音篇6项基础知识3.1.3 语音语调练习&#xff08;名言名句&#xff09;3.1.4 短文朗读练习材料&#xff08;真题&#xff09; 3.2 自我介绍与看图说话&am…

IC面试,你一定要准备好这些(内附大厂面试题目)

大家都知道&#xff0c;面试的表现会对于个人职业发展的重要性&#xff0c;不仅能决定是否录用&#xff0c;还会影响到后期的谈薪&#xff0c;所以面试前一定要做好充分的准备。 怎么准备面试&#xff1f; 这里就建议简历上的表述尽量客观化、专业化&#xff0c;多使用数字和…

目标跟踪综述 (持续更新)

这几天对目标跟踪挺感兴趣的&#xff0c;但是在CSDN和知乎上面找的相关介绍资料都看的一知半解&#xff0c;所以自己找了一篇 2022-04-26 发表的综述文章作下笔记学习下。 目录 一、基于相关滤波的目标跟踪算法 1、相关滤波视频目标跟踪算法的框架 2、相关滤波目标跟踪算法…

GPT-4开源平替miniGPT-4来了,仅需23G显存单机可run,附论文、项目代码地址

来源 | 新智元 微信号&#xff1a;AI-era 先是ChatGPT的发布给世界带来了一点小小的NLP震撼&#xff0c;随后发布的GPT-4更是破圈计算机视觉&#xff0c;展现了非凡的多模态能力。 不光能读懂人类的梗&#xff0c;给个手绘草图甚至可以直接写出网站的代码&#xff0c;彻底颠覆…

百度地图 TypeError: Cannot set properties of undefined (setting ‘Bm‘)

这类问题出现的原因一般是&#xff0c;页面还没有加载完&#xff0c;地图开始加载&#xff0c;或者地图加载在页面加载之前 在项目中&#xff0c;我用isMapLoading控制地图的加载&#xff0c;false–加载&#xff0c;true–不加载&#xff0c;在data()中设置isMapLoadingtrue

矩阵的秩的计算

definition 1 矩阵的秩 矩阵的列空间的维度 矩阵的零空间的秩 矩阵的自由变量的个数 n - r(A) definition 2 这两个证明很好证 第三个证明可以用零空间的秩 example 1 hyperlink

HTTPS建立连接原理、SSL工作原理

HTTPS与HTTP相比有什么区别&#xff1f; HTTPS保证安全的原理是什么&#xff1f; HTTPS是如何建立连接的&#xff1f; 巨人的肩膀 3.1 HTTP 常见面试题 | 小林coding HTTP与HTTPS的区别 HTTP是超文本传输协议&#xff0c;传输的内容是明文(HTTP1.1及之前版本)。HTTPS在TCP与HT…

【LeetCode】27. 移除元素

题目链接&#xff1a;https://leetcode.cn/problems/remove-element/ &#x1f4d5;题目要求&#xff1a; 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;…