深入计算机语言之C++:C到C++的过度

news2024/10/1 16:22:24

  🔑🔑博客主页:阿客不是客

🍓🍓系列专栏:从C语言到C++语言的渐深学习

欢迎来到泊舟小课堂

😘博客制作不易欢迎各位👍点赞+⭐收藏+➕关注

一、什么是C++

C++(c plus plus)是一种计算机高级程序设计语言,由C语言扩展升级而产生 ,最早于1979年由本贾尼·斯特劳斯特卢普在AT&T贝尔工作室研发。它完善了C语言的许多缺陷,并且引入了面向对象的程序设计思想,包括面向对象的四个特性:封装继承多态抽象。 

二、C++的标准库

标准的 C++ 由三个重要部分组成:

  • 核心语言,提供了所有构件块,包括变量、数据类型和常量,等等。
  • C++ 标准库,提供了大量的函数,用于操作文件、字符串等。
  • 标准模板库(STL),提供了大量的方法,用于操作数据结构等。

这三个部分包含了C++这门语言的核心,我们后面的内容就主要围绕上面三个部分展开。

三、第一个C++程序

C++兼容C语言的大多数语法,所以C语言实现的 hello world 依旧可以运行,C++中需要把定义文件代码后缀改成.cpp,vs编译器看到是.cpp就会调用C++编译器,Linux下亚勇g++编译,不再是gcc。

当然C++有一套自己的输入输出,严格说C++版本的 hello world 应该是这么写:

// test.cpp 
// 这⾥的std cout等我们都看不懂,没关系,下⾯我们会依次讲解 
#include<iostream> 
using namespace std;

int main() 
{
    cout << "hello world\n" << endl;

    return 0;
}

四、命名空间

4.1 域作用限定符

作用域限定符:  " : ",其作用是通知编译器应从作用域限定符左侧的名字所示的作用域中寻找右侧那个名字,即指定访问哪个名字空间的哪个成员。当左侧为空时,默认访问的就是全局域。

#include<iostream>

int a = 1;

int main()
{
	int a = 0;

	printf("%d\n", a);
	printf("%d\n", ::a);

	return 0;
}

我们知道C语言遵循局部优先的规则,即当局部变量与全局变量冲突时,默认使用局部变量。而在C++中,我们可以通过域作用限定符来访问全局变量。

输出结果为:

0

1

4.2 为什么要存在命名空间

在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全 局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

c语⾔项⽬类似下⾯程序这样的命名冲突是普遍存在的问题,C++引⼊namespace就是为了更好的解决这样的问题

#include<iostream>
#include<stdlib.h>
int rand = 1;
int main()
{
    printf("%d\n", rand);
    return 0;
}

当我们定义rand变量时,就会与stdlib库中的rand函数出现命名冲突,这在C语言中只能通过修改变量名称来解决。但是在C++中,我们可以就可以使用命名空间来解决。

4.3 命名空间的定义

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

C++标准库都放在⼀个叫std(standard)的命名空间中。

4.3.1 正常的命名空间定义

namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下⾯的rand不在冲突了。

#include<iostream>
#include<stdlib.h>
namespace ake
{
	int rand = 1;
}
int main()
{
	printf("%d\n", ake::rand);
	//使用域作用限定符,指定作用域
	return 0;
}

输出结果为 :1

4.3.2 命名空间的嵌套定义

namespace只能定义在全局,当然他还可以嵌套定义。

#include<iostream>
using namespace std;
namespace ake1
{
	int a = 1;
	namespace ake2//嵌套
	{
		int Add(int a, int b)
		{
			return a + b;
		}
	}
}
int main()
{
	cout << ake1::a << endl;
	//访问通过限定符依次访问
	cout << ake1::ake2::Add(1, 1) << endl;
	return 0;
}

4.3.3 多文件中同名定义合并

在同一个工程中(可以是同一个工程下的不同文件),我们可以定义多个名称相同的命名空间,在编译时命名空间会自动合并,认为是⼀个namespace,不会冲突。

namespace ake
{
	int a = 1;
}
namespace ake
{
	int b = 1;
}
//编译时会自动合并

4.4 命名空间的使用

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。所以 下⾯程序会编译报错。所以我们要使⽤命名空间中定义的变量/函数,有三种⽅式:

4.4.1 指定命名空间访问

这我们在前面已经实验演示过,现在我们来演示一下访问C++标准命名空间。(cout,endl等常用函数都被定义在C++标准命名空间std中)。

#include<iostream>
int main()
{
	std::cout << "hello bite" << std::endl;
	return 0;
}

指定命名空间访问,项⽬中推荐这种⽅式。  

4.4.2 using 部分展开

在我们书写代码时,可能会频繁调用某个函数,这是我们可以使用using部分展开,来简化代码。使用方式为using 命名空间名称:: 成员。

#include<iostream>
#include<stdlib.h>
namespace ake
{
	int a = 1;
    int b = 2;
}

using ask::a;

int main()
{
	printf("%d\n", a);
    printf("%d\n", a);
    printf("%d\n", a);
    printf("%d\n", a);
    printf("%d\n", ake::b);
	
	return 0;
}

 项⽬中经常访问的不存在冲突的成员推荐这种⽅式

4.4.3 using namespace 全部展开

除了部分展开,自然也有全局展开。其格式为using namespace 命名空间名

#include<iostream>
#include<stdlib.h>
namespace ake
{
	int a = 1;
    int b = 2;
}

using namespace ask;

int main()
{
	printf("%d\n", a);
    printf("%d\n", b);
	
	return 0;
}
展开命名空间中全部成员,项⽬不推荐,冲突⻛险很⼤,⽇常⼩练习程序为了⽅便推荐使⽤。

五、C++的输入和输出

C++的标准输入与输出函数是cincout,分别对应C语言的printf与scanf。但是相较于C语言,C++输入输出并不需要指定占位符,如:%d,%c等,输出可以⾃动识别变量类型

#include<iostream>
using namespace std;//展开命名空间
int main()
{
	cout << "hello world" << endl;
	//endl相当于换行符
	cout << "hello world" << '\n';
	cout << 'a' << endl;
	int b = 1;
	cout << b << endl;
	cout << &b << endl;
	return 0;
}

注:在C++中使用 cin 与 cout 以及 endl 都属于C++标准库,需要包含头文件iostream以及std标准命名空间。

六、缺省参数

6.1 缺省参数的使用

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

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

运行结果:

0

1

6.2 缺省参数的分类

根据其缺省参数的个数,我们我可以将缺省参数分为全缺省半缺省。

6.2.1 全缺省

每一个参数都有缺省值。

#include<iostream>
using namespace std;
void func(int a = 0, int b = 1, int c = 2)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl << endl;;
}
int main()
{
	func();//不穿参数
	func(10, 20);//半传参数
	func(10, 20, 30);//全传
	return 0;
}

6.2.2 半缺省

只有一部分参数有缺省值,并且半缺省参数必须从右往左依次来给出,不能间隔着给。同时传参只能从左往右依次传参。

#include<iostream>
using namespace std;
void func(int a ,int b=1,int c=2)
{
	cout <<"a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}
int main()
{

	func(10,20);//半传参数
	cout << endl;
	func(10, 20, 30);//全传
	return 0;
}

5.2.3 注意

在使用缺省参数时,我们也要知道一些注意事项:

1. 传参时不能间隔传参

void func(int a ,int b=1,int c=2)
{
	cout <<"a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}
func(,10,20)//error

2. 缺省参数不能在函数的声明和定义同时出现

//test.h
void Func(int a = 10);//声明
// test.cpp
void Func(int a = 20)//定义
{}

七、函数重载

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

可以通过参数类型,参数个数,参数类型顺序来构成函数重载:

int Add(int a, int b)
{
	return a + b;
}
double Add(double a, double b)//类型不同
{
	return a + b;
}
int Add(int a, int b, int c)//个数不同
{
	return a + b;
}


int Add(char a, int c)
{
	return a + c;
}
int Add(int a, char c)//类型顺序不同
{
	return a + c;
}

注意:

  1. 返回值类型不同无法构成函数重载
  2. 缺省值不同也不能构成函数重载

八、引用

8.1 引用的概念

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

引用对象类型& 引用变量名(对象名) = 引用实体;

引用类似于指针,因为指向同一块空间,所以改变引用变量引用实体也会改变。

#include<iostream>
using namespace std;
int main()
{
	int a = 1;
	int& b = a;//引用
	int& c = b;
	cout << &a << endl;
	cout << &b << endl;
	cout << &c << endl;
	c++;
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
	return 0;
}

8.2 引用的特性

8.2.1 引用时必须初始化

int& b;//错误的,必须初始化

int& b = a;

8.2.2 一个变量可以有多个引用(给别名取别名)

int a = 1;
int& b = a;
int& c = a;//多个引用

8.2.3 引用一旦引用一个实体,再不能引用其他实体

int a = 1;
int& b = a;
b = 2;//这时是赋值,相当于a = b = 2;

8.3 引用的使用

8.3.1 作为函数的参数

#include<iostream>
using namespace std;

void swap(int& a, int& b)
{
	int z = a;
	a = b;
	b = z;
}

int main()
{
	int a = 1, b = 2;
	swap(a, b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

    return 0;
}

8.3.2 做函数返回值

函数的返回值是存储在一个临时的变量里面。这个变量正常情况下是不可修改的,可以看作一个常量,我们不能对常量进行赋值。

但使用引用作为返回值相当于返回一个引用,没有中间拷贝过程和临时变量,进而同时改变了引用对象(func1(a))和被引用对象(a)。

#include<iostream>
using namespace std;

int& func1(int& a)
{
	a++;
	return a;
}

int main()
{
	int a = 1;
	func1(a) = 10;
	cout << a;
	return 0;
}

8.3.3 错误示范

1. 引用指向的空间栈帧销毁

int& func()
{
    int a = 0;
    return a;
}

返回了a的引用,但当离开函数,函数的栈帧销毁,相当于返回了一个野指针

2. 引用指向的函数多次调用

int& Add(int a, int b)
{
	int c = a + b;
	return c;
}
int main()
{
	int& ret = Add(1, 2);
	Add(3, 4);
	cout << ret <<endl;
	return 0;
}//输出什么

输出结果为:7 

那是因为在第二次调用函数Add(3,4)时,会在原来第一次调用Add(1,2)建立栈帧的空间上建立栈帧所以返回值c的值会被重新覆盖,ret是指向Add所在位置的栈帧的别名,所以ret值也会发生改变。

8.4 const引用

8.4.1 对常变量的引用(权限不可放大)

我们可以通过 const 修饰引用来让其变为常引用。这时引用变量是不能被修改的,并且只能将常变量复杂给常引用,不能将常变量赋值给引用,必须用const来引用

const int a = 10;
// 编译报错:error C2440: “初始化”: ⽆法从“const int”转换为“int &” 
// 这⾥的引⽤是对a访问权限的放⼤
//int& ra = a;

//这样才可以
const int& a = 10;
// 编译报错:error C3892: “ra”: 不能给常量赋值 
//ra++;

8.4.2 const引用普通变量(权限可缩小)

const 引⽤也可以引⽤普通变量,因为对象的访问权限在引⽤过程中可以缩⼩,但是不能放⼤。

// 这⾥的引⽤是对b访问权限的缩⼩
int b = 20; const int& rb = b;
// 编译报错:error C3892: “rb”: 不能给常量赋值
//rb++;

8.4.3 const可以引用含有常性的对象

含有常性的变量包括常数,函数返回值等。

const int& ra = 30;
int a = 1, b = 2;
const int& ra = a * 3;
const int& rb = a + b;
double d = 12.34; 
// 编译报错:“初始化”: ⽆法从“double”转换为“int &” 
// int& rd = d;
int rc = d;//隐式类型转换
const int& rd = d;

不需要注意的是类似 int& ra = a*3; int& rb = a + b; int& rd = d; 这样⼀些场景下 a*3 的运算结果和 a 保存在⼀个临时对象中。 int& rd = d 也是类似,引用时进行类型转换被称为隐式类型转换,在类型转换中会产⽣临时对象存储中间值。也就是此时,ra 和 rd 引⽤的都是临时对象,⽽C++规定临时对象具有常性,所以这⾥ 就触发了权限放⼤,必须要⽤常引⽤才可以。

所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象, C++中把这个未命名对象叫做临时对象。

注:

const int a = 10;
int& ra = a;//权限放大
int rb = a;//权限没有放大

a处于一块临时对象,只拥有读取权限,没有写入权限,此时 int& ra 是指向a所在的空间(别名),要求读取和写入的权限,所以就产生了权限放大。第二个只是将 a 的值读取拷贝给 rb,并没有产生权限放大。

const 引用传参在未来学习模板类的时候会有进行运用。

8.5 引用与指针的区别

  1. 语法概念上引⽤是⼀个变量的取别名不开空间,指针是存储⼀个地址的变量,要开空间。
  2. 引⽤在定义时必须初始化,指针建议初始化,但是语法上不是必须的。
  3. 引⽤在初始化时引⽤⼀个对象后,就不能再引⽤其他对象;⽽指针可以在不断地改变指向对象。
  4. 引⽤可以直接访问指向对象,指针需要解引⽤才是访问指向对象。
  5. sizeof中含义不同,引⽤结果为引⽤类型的⼤⼩,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8byte)
  6. 指针很容易出现空指针和野指针的问题,引⽤很少出现,引⽤使⽤起来相对更安全⼀些。

九、内联函数

在C语言中,无论宏常量还是宏函数虽能提升程序运行效,但都有易出错,无法调试等缺陷。而C++为了弥补这一缺陷,引入了内联函数的概念代替宏函数。

以关键字inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

#include<iostream>
using namespace std;
inline int Add(int x, int y)
{
	return x + y;
}
int main()
{
	Add(1, 2);
	return 0;
}

vs编译器 debug版本下⾯默认是不展开inline的,这样⽅便调试,debug版本想展开需要设置⼀下以下两个地⽅。

C/C++:常规——调试信息格式改成程序数据库,优化——内联函数扩展改成只适用于_inline

注意:

  1. 内联函数是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用。内联函数的优势减少了调用开销,提高程序运行效率,缺陷就是可能会使目标文件变大。
  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
  3. inline不能声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

因为内联函数会在调用时直接展开,编译器默认认为不需要地址,如果声明与定义分离内联函数的地址根本不会进入符号表,链接时就无法找到定义的函数,就会发生链接错误。

十、nullptr

在C语言中,定义了一个宏NULL,在传统的C头文件(stddef.h)中,可以看到如下代码 :

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

由此我们知道NULL既可以代表数字0,也可以代表空指针。这种模棱两可的定义就可能引出一些问题,比如下面这段代码:

#include<iostream>
using namespace std;
void func(int a)
{
	cout << "func(int)" << endl;
}
void func(int*p)
{
	cout << "func(int*)" << endl;
}
//函数重载
int main()
{
	func(0);
	func(NULL);
	func((int*)NULL);
	return 0;//输出??
}

我们的本意可能是将NULL当成一个指针,但是在默认情况下NULL被编译器当做数字0。这种问题是我们并不想看见的,所以C++11引入了nullptr来代替NULL。

C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,⽽不能被转换为整数类型

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

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

相关文章

stm32单片机学习 - MDK仿真调试

1 进行环境配置 点击 Options for Target&#xff0c;也就是我们俗称的魔法棒。 将"C/C"中的Optimization选项选为Level 0(-O0) 作用:优化等级调为0级,便于调试时分析代码 勾选"Debug"中的Load Application at Starup 和 Run to main() 选项 作用:Load…

DBeaver详细安装与使用教程-免费的数据库管理工具

一、简介 二、安装教程 三、使用教程 1. 连接MySQL数据库 2. 查看表数据 3. 查看表属性 3. SQL编辑器和控制台 4.在DBeaver中设置定时备份数据库 一、简介 dbeaver是一款的数据库连接工具&#xff0c;免费&#xff0c;跨平台。 官网&#xff1a;DBeaver Community | …

前端——切换轮播图

学完前端js小知识后&#xff0c;动手操作的一个简单图片轮播图。 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"keywords" content"关键词信息"><meta name"des…

数据中心交换机与普通交换机之间的区别到底在哪里?

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 上午好&#xff0c;我的网工朋友。 数据中心交换被设计用来满足数据中心特有的高性能、高可靠性和可扩展性需求。 与此同时&#xff0c;普通交换机…

ACL(Access Control List)访问控制列表

目录 ACL 访问控制列表 ACL分类 ACL的组成 ACL匹配机制 ACL调用方式 实验配置 不允许PC1访问PC4 只允许PC1访问PC4 高级ACL 基本概念 实验配置 限制ping 实验配置 限制DNS 基于时间的ACL 实验配置 ACL 访问控制列表 根据一系列不同的规则&#xff0c;设备根据这…

使用Python实现Auto.js的自动输入图形验证码

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【unity进阶知识6】Resources的使用,如何封装一个Resources资源管理器

文章目录 一、Unity资源加载的几种方式1、Inspector窗口拖拽2、Resources3、AssetBundle4、Addressables&#xff08;可寻址资源系统&#xff09;5、AssetDatabase 二、准备三、同步加载Resources资源1、Resources.Load同步加载单个资源1.1、基本加载1.2、加载指定类型的资源1.…

详解JavaScript中把函数作为值

8.4 作为值的函数 JS中函数不仅是一种语法&#xff0c;也是值&#xff0c;也就是说&#xff0c;可以将函数赋值给变量&#xff0c;存储在对象的属性或者数组的元素中&#xff0c;作为参数传入另外一个函数等。 来看一个函数&#xff1a;function square(x){return x*x;} 定义…

深度学习之入门书籍

自学深度学习&#xff0c;书籍很重要。 从我个人来说&#xff0c;我不太习惯英译版本&#xff0c;或者那些牛人说的&#xff0c;直接读英文&#xff0c;我是水平不够。只讲自己的经验。牛人绕道。 推荐书籍: 深度学习:从入门到精通&#xff0c;这本书不错。把基础的深度学习的…

自然语言处理问答系统技术

自然语言处理问答系统技术 随着人工智能的不断发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术已成为推动智能问答系统发展的核心技术。问答系统是利用NLP来解析用户提出的问题&#xff0c;并从知识库中找到最相关的答案。在许多应用中&#xff0c;如智能客服、…

用 LoRA 微调 Stable Diffusion:拆开炼丹炉,动手实现你的第一次 AI 绘画

总得拆开炼丹炉看看是什么样的。这篇文章将带你从代码层面一步步实现 AI 文本生成图像&#xff08;Text-to-Image&#xff09;中的 LoRA 微调过程&#xff0c;你将&#xff1a; 了解 Trigger Words&#xff08;触发词&#xff09;到底是什么&#xff0c;以及它们如何影响生成结…

构建企业数字化转型的战略基石——TOGAF框架的深度解析

数字化时代的企业变革需求 在全球范围内&#xff0c;数字化转型已成为企业提高竞争力、优化运营流程、提升客户体验的核心战略。数字技术的迅猛发展&#xff0c;不仅改变了传统行业的运作模式&#xff0c;也迫使企业重新思考其业务架构和技术基础设施。TOGAF&#xff08;The O…

用示波器测动态滞回线

大学物理&#xff08;下&#xff09;实验-中南民族大学通信工程2022级 手动逐个处理数据较为麻烦且还要绘图&#xff0c;故想到用pythonmatplotlib来计算结果并数据可视化。 代码实现 import matplotlib.pyplot as plt# 样品一磁化曲线 X [0, 0.2, 0.4, 0.6, 0.8, 1, 1.5, 2.…

实战笔记:Vue2项目Webpack 3升级到Webpack 4的实操指南

在Web开发领域&#xff0c;保持技术的更新是非常重要的。随着前端构建工具的快速发展&#xff0c;Webpack已经更新到5.x版本&#xff0c;如果你正在使用Vue2项目&#xff0c;并且还在使用Webpack 3&#xff0c;那么是时候考虑升级一下Webpack了。我最近将我的Vue2项目从Webpack…

TDesign组件库+vue3+ts 如何视觉上合并相同内容的table列?(自定义合并table列)

背景 当table的某一列的某些内容相同时&#xff0c;需要在视觉上合并这一部分的内容为同个单元格 如上图所示&#xff0c;比如需要合并当申请人为同个字段的列。 解决代码 <t-table:data"filteredData":columns"columns":rowspan-and-colspan"…

psutil库的使用说明

前言 psutil是一个跨平台的库&#xff0c;用于获取系统的进程和系统利用率&#xff08;包括 CPU、内存、磁盘、网络等&#xff09;信息。 目录 安装 应用场景 常用方法 一、系统信息相关函数 二、进程信息相关函数 三、网络信息相关函数 四、其他实用函数 使用样例 监控应…

YOLOv11改进 | Neck篇 | YOLOv11引入BiFPN双向特征金字塔网络

1.BiFPN介绍 摘要&#xff1a;模型效率在计算机视觉中变得越来越重要。 在本文中&#xff0c;我们系统地研究了用于目标检测的神经网络架构设计选择&#xff0c;并提出了几个提高效率的关键优化。 首先&#xff0c;我们提出了一种加权双向特征金字塔网络&#xff08;BiFPN&…

【Linux服务器】git和github交互使用

前言&#xff1a;有时候pycharm连接不上github&#xff0c;还是得命令行操作 目录 1. 准备git2. 配置github账户3. 上传项目3.1 创建本地仓库3.2 提交本地代码3.3 上传到github 4. 注意 1. 准备git 下载链接&#xff1a;官网 下载后直接运行安装&#xff0c;cmd输入git --vers…

基于Springboot+Vue的农场投入品运营线上管理系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 在这个…

Kali Linux语言设置成中文

要将Kali Linux设置成中国地区&#xff08;简体中文&#xff09;&#xff0c;可以按照以下步骤进行操作&#xff1a; 一、更新软件包列表 打开Kali Linux的终端。输入以下命令来更新软件包列表&#xff1a; sudo apt-get update二、安装语言包 输入以下命令来安装locales包…