「C++」入门

🎇个人主页:Ice_Sugar_7
🎇所属专栏:C++启航
🎇欢迎点赞收藏加关注哦!

文章目录

  • 🍉前言
  • 🍉命名空间
    • 🍌访问命名空间中的元素
    • 🍌同名命名空间
    • 🍌展开
      • 🥝指定展开
  • 🍉io流
    • 🍌基本的输入输出
  • 🍉缺省参数
    • 🍌使用规则
  • 🍉函数重载
    • 🍌补充
  • 🍉引用
    • 🍌注意事项
    • 🍌常引用
    • 🍌相关应用
      • 🥝传参
      • 🥝作为返回值
    • 🍌引用的底层实现
    • 🍌引用与指针的区别
  • 🍉内联函数
    • 🍌基本概念
    • 🍌注意事项&建议
  • 🍉关键字:auto
  • 🍉范围for循环
  • 🍉指针空值nullptr

🍉前言

cpp在绝大部分情况下都兼容C语言,相当于C语言的拓展,所以在正式进入cpp的世界之前,我们得先了解相较于C语言,cpp有哪些不同之处,然后才能入门。

🍉命名空间

在写代码的过程中,我们自己写的函数可能与库函数冲突(函数名相同),而在一个项目中,我定义的某个类型或者函数有可能和你的定义一样,我们单独运行自己的代码没问题,但是一旦合并到一个项目中运行就会产生冲突。
这时除了改变我们两人其中一个的代码的名字,我们可以使用命名空间,它的形式如下:

namespace space {int a = 0;
}

类似结构体,但是大括号后面没有分号,里面可以存放变量、函数、某种类型等

命名空间相当于一堵墙,将其中的元素与全局隔离开了,在找变量的时候,会去找全局中的变量,哪怕找不到,也不会去找命名空间中的。

🍌访问命名空间中的元素

访问的话很简单,只需按照命名空间名 + :: + 你想访问的元素的格式就ok,例子如下:

namespace space {int c = 10;
}int a = 10;printf("%d\n", space::c);

🍌同名命名空间

多个文件中含有同名的命名空间,它们不会产生冲突。

比如你在头文件里面定义了一个命名空间,源文件里面也有一个同样的命名空间,这个源文件在包含头文件的时候,编译器会自动识别将它们进行合并,因此不会发生冲突。

🍌展开

展开就相当于你把这堵围墙给拆了

展开后搜索顺序
我现在同时展开两个命名空间,又定义了一个变量,那会如何搜索呢?

	using namespace a{//...};using namespace b{//...};

规则是这样的:先搜索全局,全局找到了就不会搜索这两个命名空间;如果找不到再来它们里面找,从上往下找,即先找a,a找不到再找b,a找到的话那自然不用去b里面找咯。(都找不到的话那就报错了)

拓展:
头文件展开:在预处理阶段把头文件的内容拷贝过来
命名空间展开:默认访问命名空间中的变量而非全局中的变量

只要你展开了,那默认就会去命名空间中搜索,不用每次都要去指定。(要指定也可以,只不过一般不那么做)

那接下来我们来看下它是啥意思

	using namespace std;

std是cpp官方库定义的命名空间,cpp库里面的东西都在它里面,你把它展开之后就可以使用cpp的东西了

注意:以后在工程项目中,不要随便展开std,因为很有可能会与里面的函数发生冲突(不然你想下为啥要把它们封装在std里面),而现在日常的练习之中,由于代码量比较小,发生冲突的概率很小,所以一般就直接展开了。

🥝指定展开

不展开的话每一次都要指定很麻烦,全部展开的话又会有冲突的风险,那怎么办呢?这时候就要用到指定展开
要用啥就展开啥,只展开一部分才是最稳妥的方式

using space::add;	//只展开space中的函数add,此时可在任意位置使用add

🍉io流

我们在cpp中通常会包含这样一个头文件:

#include<iostream>

里面包含cin、cout、<<等输入输出函数,相当于C语言的stdio.h,然后注意cpp中包含io流不用写“.h”

在C语言中 << 是一个位运算符,在cpp中它有了新的含义一一流插入运算符;相应地,>>叫做流提取运算符
(说到流入和提取,以及看到 in 和 out,不禁回想起之前学习文件操作时接触到的“输入流”和“输出流”,输入流就是把流里面的数据给到文件,而输出流则是把数据从文件中提取出来,放到流里面。)

🍌基本的输入输出

using namespace std;int main(){int a = 10;cout << a << endl;int b;cin >> b;cout << b << endl;int c, d;cin >> c >> d;  //输入两个数cout << c << ' ' << d << endl;  //输出c,d并用空格分隔return 0;
}

输出结果:
在这里插入图片描述
cpp中的cout会自动识别类型,不用和printf一样还要去区分%d,%lf 什么的,比如上面把c改为浮点型,照样可以正常输出。

关于控制浮点数位数以及左、右对齐:这两个点用cin和cout不好实现,但是我们可以用printf,毕竟cpp兼容C语言,两个混用也是ok的,哪个方便用哪个就是了。


🍉缺省参数

以前学C语言的时候,如果函数如果有形参,那我们传参时就要传个参数过去。而C++中有了缺省参数这个概念,我们可以选择不传参,此时缺省参数会作为参数进行传参。其实说白了它就相当于一个备胎,实参部分有参数时就轮不到它,没有的时候才能上场。

int mul(int a = 10, int b = 20) {return a * b;
}int main() {int a, b;cin >> a >> b;cout << mul(a, b)<< endl;cout << mul() << endl;  //使用缺省参数
}

在这里插入图片描述

🍌使用规则

使用缺省参数时需注意:
①只能自右向左缺省,若有多个缺省参数,则必须连续缺省,比如下面两个函数声明就犯了这种错误。

int func1(int a = 10, int b, int c);   //不是从右向左缺省
int func2(int a = 10, int b,int c = 20);   //没有连续缺省

②函数不能在声明和定义同时出现缺省参数
这样规定的理由其实很好理解,要是你声明函数和定义函数时设置的缺省参数不一样的话,那就不知道要选谁作为缺省参数了。(一般函数声明和定义不在同一个文件)
③缺省参数值只能为常量或者全局变量


🍉函数重载

cpp支持函数重载,在函数名相同的情况下,只要参数不一样,那么这两个函数就可以共存。

参数不同包括:①参数类型不同;②参数个数不同

比如

int func(int x, char y);
int func(char x, int y);

C语言在链接时是通过函数名去寻找函数地址,所以不允许出现同名函数;而cpp中采用函数名修饰规则,链接时根据修饰后的函数名去寻找函数的地址
在Linux环境下,通过指令 objdump -S 可执行程序可以查看函数名修饰后的情况。
比如,对于下面这个函数:

void func(int a,double b) {//...
}

如下图,可以看到它的函数修饰名为_Z4funcid
其中_Z为函数修饰名前缀;4表示函数名所占的字符数i表示整型参数;d表示双精度浮点型的参数。同时你会发现函数修饰名中没有包含返回值,这也说明两个函数仅有返回值不同是无法构成重载的
在这里插入图片描述

🍌补充

将一个源文件转化为可执行程序(.exe)需要经过预处理、编译、汇编和链接四个步骤

预处理阶段会进行头文件展开、宏替换、条件编译(去除条件语句中不用执行的语句)、去除注释等操作
编译阶段会检查语法,生成汇编代码,编译错误就是因为语法出错
汇编阶段会将汇编代码转换为二进制的机器代码
链接阶段会将各个文件合并起来,链接一些还没有确定的函数地址

将代码转到反汇编可以看到汇编代码,如下:
在这里插入图片描述其中的push、mov、sub都是我们可以看懂的,但是机器只认识二进制代码,所以汇编阶段要将它们转为二进制。


🍉引用

引用是给一个已经存在的变量再起一个“别名”,它和被引用的变量共用同一块内存空间
在这里插入图片描述
(如上图,b就是a的引用)

🍌注意事项

①引用必须初始化,即不能直接 int& b;
②一个变量可以同时有多个引用。毕竟是别名,多起几个也没事儿。

	int a = 1;int& b = a;int& c = b;int& d = a;

③引用无法改变指向。如下图,比如b是a的指向,那么就不能再让b成为c的引用。也正是这个特性,使得引用无法完全替代指针
在这里插入图片描述

🍌常引用

我们都知道,常量不可以被修改,但是引用可以对原数据进行修改,所以直接对常量进行引用就相当于放大了权限(从不可修改变为可以修改),编译器会报错。想引用常量的话,只需在引用前面加上const就ok了。

void TestConstRef()
{const int a = 10;//int& ra = a;   // 该语句编译时会出错,a为常量const int& ra = a;// int& b = 10; // 该语句编译时会出错,b为常量const int& b = 10;
}

🍌相关应用

🥝传参

在实现单链表的尾插时,我们说当链表为空,想插入节点要传链表的二级指针,这样才能改变节点。但是这样确实很麻烦,也不好理解。而对于引用,由于它作为函数形参时,和实参共用同一块空间,所以改变它会影响实参,比传二级指针简洁多了。下面以这个函数为例进行对比
指针

void SLPushBack(SLNode** pphead,SLTypeDate x) {assert(pphead);  //进行断言,防止传过来的指针为空SLNode* node = SLBuyNode(x);if (*pphead == NULL) {  //phead为空说明此时链表为空,那就直接插入*pphead = node;  //让node是第一个节点的地址return;}//若不为空,则先找到链表的最后一个节点,再插入SLNode* pcur = *pphead;  //老样子,用临时变量pcur去走循环while (pcur->next) {pcur = pcur->next;}//此时pcur指向最后一个节点pcur->next = node;
}

引用

void SLPushBack(SLNode*& phead, SLTypeDate x) {assert(phead);  SLNode* node = SLBuyNode(x);if (phead == NULL) {  phead = node;  return;}SLNode* pcur = phead;  while (pcur->next) {pcur = pcur->next;}pcur->next = node;
}

🥝作为返回值

传值返回首先会对返回值进行拷贝,然后返回这份拷贝;对于传引用返回,也就是返回n的别名(你不用去理会这个别名叫什么,编译器会自行处理的,或者直接理解为返回n)。那此时到底会返回什么呢?这取决于栈帧结束后编译器会不会将栈帧内的值置为随机值并清理掉。我们来做个测试看看vs2022的编译器是否会进行清理。

int& test1(int i) {int data = i;return data;
}int main() {int& ret = test1(10);cout << ret << endl;return 0;
}

在这里插入图片描述
由此可见,vs2022在函数栈帧结束后不会将栈帧中创建的变量清理掉

🍌引用的底层实现

在语法概念上,指针有开辟一块空间,而引用没有独立的空间。
不过对于这段代码,我们进行调试并转到反汇编观察一下。

	int x = 1;int* px = &x;int& y = x;

在这里插入图片描述
可以看到,引用和指针的汇编代码一模一样,说明引用在底层实现实际上是有开辟空间的,因为引用是按照指针的方式来实现的,即引用的底层是通过指针实现的
尽管如此,你也不要与上面的语法概念产生混淆,因为语法概念是上层的,而汇编是底层的。我们要按照语法概念来理解,默认引用就只是个别名

🍌引用与指针的区别

在现阶段大部分场景下,只要不涉及改变指向,就基本可以用引用代替指针。下面总结一下二者的区别(有一些上面已经讲过了,就不再赘述):

有NULL指针,但没有NULL引用,
引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
有多级指针,但是没有多级引用
访问实体方式不同,指针需要显式解引用,引用编译器自己处理
引用比指针使用起来相对更安全(比如说有野指针,但是没有野引用)
在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)


🍉内联函数

🍌基本概念

用inline修饰的函数叫做内联函数,在编译阶段,C++编译器会在调用内联函数的地方展开,用函数体替换函数调用,没有函数调用建立栈帧的开销,可以提升程序运行的效率。
注意:在release模式下才会展开,debug模式下仍然会调用函数(因为debug模式下,编译器默认不会对代码进行优化)。

inline int Add(int x, int y) {return x + y;
}int main() {cout << Add(1, 2) << endl;return 0;
}

在debug模式下观察汇编代码:
在这里插入图片描述
在release模式下,没有跳转到Add函数的指令:
在这里插入图片描述

🍌注意事项&建议

假设现在要实现一个栈,那就需要有Stack.h、Stack.cpp和test.cpp三个文件。
如果声明时在函数前面加上inline使其变为内联函数(假设在编译时这个函数会展开),那么会产生什么影响呢?

对于test.cpp文件,里面只有包含的头文件(函数声明)和函数的调用,在链接的时候需要去找函数的地址(链接时每个cpp文件生成的.o文件中都有一个符号表),但是内联函数的地址是不会进入符号表的,所以也就找不到它的地址了,就会产生链接错误了。
对于Stack.cpp文件,因为它本身就有函数的实现,编译时函数体直接展开,因此不需要得到函数的地址

所以我们可以得到这样的结论:一个内联函数如果声明和定义不在同一个文件的话,那么你就不能在其他文件(除Func.h 和 Func.cpp 之外的文件)中调用它
下面是一个链接错误的例子:

// F.h
#include <iostream>
using namespace std;
inline void f(int i);// F.cpp
#include "F.h"
void f(int i)
{cout << i << endl;
}// main.cpp
#include "F.h"
int main()
{f(10);return 0;
}
// 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl 
f(int)" (?f@@YAXH@Z),该符号在函数 _main 中被引用

内联确实可以提高运行效率,但是不可乱用,比较大的函数采用内联直接展开的话会增加占用空间,使生成的可执行程序变大。为了防止程序员滥用,内联函数最终是否展开取决于编译器的处理,也就是说内联相当于是向编译器发出请求,编译器可以执行,也可以忽略。一般较大的函数即使加了inline,编译器也会忽略,不会直接展开。
所以,建议代码量较小的频繁调用的函数在前面加inline。


🍉关键字:auto

随着程序越来越复杂,程序中用到的类型也越来越复杂,体现在:

①类型难于拼写
②含义不明确导致容易出错

为了解决这些问题,C++11中,auto可以识别右值的类型并自动转换为相应的类型
在愉悦地上手auto之前,有如下的注意事项:

auto定义变量时必须初始化
用auto声明指针类型时,用auto和auto*没有任何区别,但是用auto声明引用类型时必须加&

int main()
{int x = 10;auto a = &x;auto* b = &x;auto& c = x;cout << typeid(a).name() << endl;  //获取变量a的类型,了解即可cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;*a = 20;*b = 30;c = 40;return 0;
}

在同一行定义多个变量时,变量类型必须相同,否则编译器会报错。因为编译器只会对第一个变量进行推导,然后用推导出来的类型去定义其他变量

void TestAuto()
{auto a = 1, b = 2; auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}

auto不能做函数参数,也不能做返回值


🍉范围for循环

C++11中引入了基于范围的for循环,for循环后的括号由冒号:分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示迭代的范围
光看文字肯定看不太懂,看下程序就明白了

void TestFor()
{int array[] = { 1, 2, 3, 4, 5 };for(auto& e : array)  //一般用auto,这样数组类型改变的时候你不用去修改e *= 2;for(auto e : array)cout << e << " ";return 0;
}

对于第一个范围for循环,就是依次取数组中的元素,然后赋值给e,再让e乘2,因为这里使用了引用,所以改变e就会改变数组中的元素。数组第一个元素乘2之后会自动往后走(相当于i++),让第二个元素赋值给e之后乘2…直到最后一个元素,然后自动判断结束。
如果不使用引用,写为for(auto e:array)的话,在循环中让e*2不会改变数组中的数据,因为只是把数组的值赋给e,改变e当然没法改变数组元素的值咯。

范围for相比与以前for循环,最大的进步就是不用自己去判断循环的终止条件了,这样既节省了时间,也可以避免写错终止条件而出错。

照例还是有一些注意事项:

①范围for中的数组名指的是整个数组(类比sizeof(数组名)),所以数组作为函数参数时,不能在函数中使用范围for,因为此时数组名表示的是首元素地址
②与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环
③范围for循环迭代的范围必须是确定的(对于数组而言,就是数组中第一个元素和最后一个元素的范围)
④迭代的对象要实现++和==的操作


🍉指针空值nullptr

在C++中,NULL被编译器识别为0而非void*
可以用以下程序证明:

void TestNULL(int* p) {cout << "int*" << endl;
}void TestNULL(int p) {cout << "int" << endl;
}int main() {TestNULL(NULL);  //根据输出结果判断NULL的类型return 0;
}

在这里插入图片描述
如果NULL是0的话,那么用它来给指针置空的话,很可能会出问题。
为了修补这个漏洞,C++11中引进nullptr专门给指针置空。因此以后对于指针类型的变量,如果我们要初始化为空,就用nullptr

注意事项:

①因为nullptr是C++11新的关键字,所以在使用nullptr表示指针空值时,不需要包含头文件,
②在C++11中,nullptrvoid*所占的字节数相同
③为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr

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

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

相关文章

2018年1月22日 Go生态洞察:Hello, 中国!

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

C语言之指针知识点总结

C语言之指针知识点总结 文章目录 C语言之指针知识点总结1. 初识指针1.1 取地址操作符 &1.2 指针变量1.3 解引用操作符 *1.4 指针变量1.4.1 大小1.4.2 指针类型的意义 1.5 void*指针1.6 const关键字1.61 const修饰变量1.6.2 const修饰指针变量 1.7 指针的运算1.7.1 指针-整数…

pyhon数据分析A股股票策略实际买卖总结(每月末更新数据)

简介 本篇文章主要记录python数据分析a股股票选股后实际买卖的记录。 选股策略 低位寻股&#xff0c;筛选出低位股价股票已经做过调整的股票&#xff0c;做短线交易&#xff08;不超过7天&#xff09;&#xff0c;不贪&#xff0c;小赚即走。分三个时段&#xff0c;开盘三十…

SAS9.2软件“OLE:对象的类没有在注册数据库中注册“问题的解决. 2023-11-25

操作系统测试平台: Win7 sp1 32bit (6.1.7601.26321 (Win7 RTM)) ; Win 11 64bit(具体版本不详) 其它win平台理论上也可以,可自行测试 1.安装依赖库(必要步骤) 下载地址: Microsoft Visual C 2005 Redistributable 下载 Microsoft Visual C 2008 Redistributable 官方vc库总…

buuctf web [极客大挑战 2019]PHP

提示有备份,dirsearch扫描网站备份 GitHub - maurosoria/dirsearch: Web path scanner下载.zip格式文件 解压到python目录下 在上图位置cmd打开窗口 输入python setup.py install安装dirsearch 安装好后输入命令使用dirsearch python dirsearch.py -u http://44296191-973d-…

第一百八十回 介绍两种阴影效果

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"自定义SlideImageSwitch组件"相关的内容&#xff0c;本章回中将介绍两种阴影效果.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在…

【深入剖析K8s】容器技术基础(一):从进程开始说起

容器其实是一种特殊的进程而已。 可执行镜像 为了能够让这些代码正常运行’我们往往还要给它提供数据’比如我们这个加法程序所需要的输人文件这些数据加上代码本身的二进制文件放在磁盘上’就是我们平常所说的一个程序,也叫代码的可执行镜像&#xff08;executablejmage&…

用xlwings新建一个excel并同时生成多个sheet

新建一个excel并同时生成多个sheet&#xff0c;要实现如下效果&#xff1a; 一般要使用数据透视表来快速实现。 今天记录用xlwings新建一个excel并同时生成多个sheet。 import xlwings as xw # 打开excel,参数visible表示处理过程是否可视,add_book表示是否打开新的Excel程序…

CSDN助手:一键下载CSDN博客:高效保存,随时阅读

文章目录 &#x1f4d6; 介绍 &#x1f4d6;&#x1f3e1; 环境 &#x1f3e1;&#x1f4d2; 使用方法 &#x1f4d2;⚓️ 相关链接 ⚓️ &#x1f4d6; 介绍 &#x1f4d6; 这是我自己无聊的时候写的一个应用&#xff0c;以前UI有点丑&#xff0c;这次重写了一下UI 功能如下 …

vue+elementui如何实现在表格中点击按钮预览图片?

效果图如上&#xff1a; 使用el-image-viewer 重点 &#xff1a; 引入 import ElImageViewer from "element-ui/packages/image/src/image-viewer"; <template><div class"preview-table"><el-table border :data"tableData" …

使用VC++设计程序:实现常见的三种图像插值算法:最近邻插值,双线性插值,立方卷积插值

图像放大的三种插值算法 获取源工程可访问gitee可在此工程的基础上进行学习。 该工程的其他文章&#xff1a; 01- 一元熵值、二维熵值 02- 图像平移变换&#xff0c;图像缩放、图像裁剪、图像对角线镜像以及图像的旋转 03-邻域平均平滑算法、中值滤波算法、K近邻均值滤波器 04-…

电子学会C/C++编程等级考试2022年09月(二级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:统计误差范围内的数 统计一个整数序列中与指定数字m误差范围小于等于X的数的个数。 时间限制:5000 内存限制:65536输入 输入包含三行: 第一行为N,表示整数序列的长度(N <= 100); 第二行为N个整数,整数之间以一个空格分…

Deepin使用记录-deepin系统开启SSH服务

1、检查安装的deepin系统是否已经开启SSH功能。 $ ps -e | grep ssh $ ps -e | grep ssh 查看是否启动ssh 2、安装openssh-server服务 sudo apt-get install openssh-server 如果出现以上提示&#xff0c;就表示你已经安装了ssh服务&#xff0c;只是还没有启动。 3、安装完…

快速幂算法详解(C++实现)

文章目录 1. 什么是快速幂2. 暴力求解代码实现缺陷分析 3. 优化一&#xff1a;取模运算的性质4. 优化二&#xff1a;快速幂算法的核心思想5. 终极优化&#xff1a;位运算优化6. 源码 这篇文章我们来一起学习一个算法——快速幂算法。 1. 什么是快速幂 顾名思义&#xff0c;快速…

leetCode 1080.根到叶路径上的不足节点 + 递归

给你二叉树的根节点 root 和一个整数 limit &#xff0c;请你同时删除树中所有 不足节点 &#xff0c;并返回最终二叉树的根节点。假如通过节点 node 的每种可能的 “根-叶” 路径上值的总和全都小于给定的 limit&#xff0c;则该节点被称之为 不足节点 &#xff0c;需要被删除…

C语言-内存函数详解

文章目录 1. memcpy使用和模拟实现2. memmove使用和模拟实现3. memset函数的使用4. memcmp函数的使用 1. memcpy使用和模拟实现 返回类型和参数&#xff1a; void * memcpy ( void * destination, const void * source, size_t num );1.函数memcpy从source的位置开始向后复制…

R语言实现Lasso回归

一、Lasso回归 Lasso 回归&#xff08;Least Absolute Shrinkage and Selection Operator Regression&#xff09;是一种用于线性回归和特征选择的统计方法。它在回归问题中加入了L1正则化项&#xff0c;有助于解决多重共线性&#xff08;多个特征高度相关&#xff09;和特征选…

设备树是什么?

设备树&#xff1a; 设备树DTS(Device Tree Source) 描述设备信息的独立的文件。 为什么要引入设备树&#xff1f; 随着芯片的发展&#xff0c;Linux内核中就包含着越来越多这些描述设备的代码&#xff0c;导致Linux内核代码会很臃肿。因此引入了设备树文件&#xff0c;从…

基于 GPS 定位信息的 Pure-Pursuit 轨迹跟踪实车测试(1)

基于 GPS 定位信息的 Pure-Pursuit 轨迹跟踪实车测试&#xff08;1&#xff09; 进行了多组实验&#xff0c;包括顺逆时针转向&#xff0c;直线圆弧轨迹行驶&#xff0c;以及Pure-Pursuit 轨迹跟踪测试 代码修改 需要修改的代码并不多&#xff0c;主要对 gps_sensor 功能包和…

Java中的泛型是什么?如何使用泛型类和泛型方法?

Java 中的泛型是一种编程机制&#xff0c;允许你编写可以与多种数据类型一起工作的代码&#xff0c;同时提供编译时类型检查以确保类型的安全性。泛型的主要目的是提高代码的可重用性、类型安全性和程序的整体性能。 泛型类&#xff08;Generic Class&#xff09;: 在泛型类中…