单位建网站怎么做/百度贴吧官网入口
vector引入
vector的实现主要依靠三个成员变量:
start,finish和end_of_storage
其中:
[start]
指向容器中的起始位置
[finish
]指向容器中最后一个有效数据的下一个位置
[end_of_storage]
指向容器中现有容量的位置
通过这三个指针,就使得vector
的size()
=finish - start
capacity
=end_of_storage
-start
.成员函数
[函数模板]
为了使我们的vector实用性更好,我们需要使用函数模板。
[迭代器]
构造函数
上面是vector的构造函数,每个构造函数的使用如下:
我们根据这里提供的接口自己实现构造函数。
[默认构造]
[迭代器构造]
左边是迭代器构造函数的实现,右边是调用迭代器构造,发现确实是调用了迭代器构造。
需要注意的地方为什么迭代器要使用模板?因为我们不知道传进来的是什么类型,就需要用模板来接收,保证泛型编程。
[拷贝构造函数]
下面有两种拷贝构造函数的实现,都是错误的,因为这是浅拷贝。
浅拷贝会导致两个vector指向同一个地址空间。
对v1的操作同时也是对v的操作了。
浅拷贝对内置类型没有影响,因为不会对堆上的内容进行析构。
例如下面这样:
但是浅拷贝对自定义类型影响很大,会导致析构的的时候析构两次,导致崩溃:
//1.4 拷贝构造 -- 用v来初始化thisvector(const vector<T>& v){//注意:不能使用memcpy,memcpy是浅拷贝_start = new T[v.capacity()]; //开辟一块新的空间for (size_t i = 0; i < v.size(); ++i){_start[i] = v[i];}_finish = _start + v.size();_end_of_storage = _start + v.capacity();}
对拷贝构造函数进行测试:
[赋值运算符重载函数]
需要注意的地方有两个:
1. 判断一下,不能自己给自己赋值
2. 要先释放掉原来的空间
vector<T>& operator=(const vector<T> &v){//防止自己给自己赋值if (this != &v){//1.释放掉原来的空间delete[] _start;_start = new T[v.capacity()];for (int i = 0; i < v.size(); ++i){_start[i] = v[i];}_finish = _start + v.size();_end_of_storage = _start + v.capacity();}return *this;}
对赋值运算符重载函数进行测试:
n个值构造因为涉及调用resize()函数,所以放在后面写。
扩容函数
实现reserve()函数 reserve()函数实现逻辑是什么?
[reserve()函数]
这样写会出现什么问题? 我们用如下代码对reserve()进行测试。
测试结果如下:
这是因为在计算新空间的_finish的时候,调用的是size()函数。
先看看size()函数是如何实现的?
因此,改进的方式,是在_start指向新空间之前将size()的内容存储下来。
void reserve(size_t n){if (n <= capacity()){//不进行任何操作}else{//先将size()的内容存储下来int sz = size();//这里的扩容是开辟一块空间,将旧的内容拷贝的新空间上T* tmp = new T[n]; if (_start){for (int i = 0; i < size(); ++i){tmp[i] = _start[i];}//释放掉以前的空间delete[] _start;}//让_start指向新开辟的空间_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}}
运行测试:
resize()函数]
实现resize()函数可以分为三种情况:
1.n <= _finish
2.n >_finish && n <= _end_of_storage
3.n > _end_of_storage
其实,前两种可以合并成一种。因为他们都不需要对vector进行扩容。
后面的一种需要对vector进行扩容,可以使用reserve()函数进行复用。
resize()函数的具体实现:
void resize(size_t n, const T& value = T()){if (n <= size()){_finish = _start + n;}else{//1.扩容reserve(n);//2.将内容插入到vector中while (_finish != _start + n){*_finish = value;++_finish;}}}
测试:
测试n个值构造的时候,出现报错,非法的间接寻址:
首先弄明白,什么是非法的间接寻址?
只有指针和迭代器可以解引用,内置类型不能解引用。而如果对内置类型解引用,就会出现非法的间接寻址。
为什么明明我们调用的是n个值的构造函数,确走到了迭代器初始化?这就要提一下最匹配的问题了。因为我们传递的是int类型,但是n个值的构造函数却是size_t类型。所以不是最匹配,就会走到迭代器构造函数这里来。
因此,解决办法就是调用最匹配的构造函数,对原来的构造函数进行重载即可。
修改
[pop_back()函数]
函数实现:
不需要将删除的元素置空,只用挪动_finish指针,以后有新的操作时,直接对原数据进行覆盖
对函数进行测试:
[pop_back()函数]
void push_back(const T& x)
{if (_finish == _end_of_storage){size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newCapacity);}*_finish = x;_finish++;
}
[insert()函数]
迭代器失效问题
_finish
是最后一个元素的下一个位置。我们要插入值,就需要找到最后一个元素,并且将这些元素一个一个往后挪动,直到空出pos
的位置,插入value
实现逻辑如下:
void insert(iterator pos, const T& val){assert(pos >= _start && pos <= _finish);//1.判断扩容逻辑if (_finish == _end_of_storage){int newCapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newCapacity);}//2.将pos后的内容往后移动auto end = _finish - 1; //_finish指向的是最后一个元素的下一个位置while (end >= pos){*(end + 1) = *end;--end;}//3.将val插入到vector中*pos = val;++_finish;}
当没有扩容时,对函数进行测试:
一旦前面进行扩容:
插入的数是随机数。
这就是内部迭代器失效的问题。
为什么会出现迭代器失效的问题?
从刚刚的测试可以看出,迭代器失效应该是和是否扩容有关的,我们从调试的角度来看看。
扩容之前_start
和pos
的内容:
扩容之后,_start
因为使用reserve()
进行异地扩容,位置就会发生改变,而pos
没有改变位置。会导致后面的pos
和end
无法比较:
通过图示更直观的理解:
解决办法就是,让pos
和_start
一起走。计算出pos
和_star
t之间的偏移量,在_start
换到新的地址之后,根据偏移量计算出pos
的新位置。
代码:
void insert(iterator pos, const T& val){assert(pos >= _start && pos <= _finish);//1.判断扩容逻辑if (_finish == _end_of_storage){//1.1计算出pos和_start的偏移量int n = _start - pos;int newCapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newCapacity);//1.2扩容完之后根据偏移量找到新pos的位置pos = _start + n;}//2.将pos后的内容往后移动auto end = _finish - 1; //_finish指向的是最后一个元素的下一个位置while (end >= pos){*(end + 1) = *end;--end;}//3.将val插入到vector中*pos = val;++_finish;}
运行结果:
解决完内部迭代器失效问题之后,还存在外部迭代器失效的情况。什么是外部迭代器失效?
用自己写的vector,看看会出现什么结果:
对迭代器解引用是随机值,这就代表迭代器失效了。为什么会失效?
因为我们调用insert()插入值之后,迭代器的位置会改变,因此就失效了。
如何解决外部迭代器失效的问题呢?
1.在insert()函数中返回迭代器
2.在调用insert()之后接收改变后的迭代器必须要接收迭代器,不然还是会出现迭代器失效的问题。
iterator insert(iterator pos, const T& val){assert(pos >= _start && pos <= _finish);//1.判断扩容逻辑if (_finish == _end_of_storage){//1.1计算出pos和_start的偏移量int n = _start - pos;int newCapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newCapacity);//1.2扩容完之后根据偏移量找到新pos的位置pos = _start + n;}//2.将pos后的内容往后移动auto end = _finish - 1; //_finish指向的是最后一个元素的下一个位置while (end >= pos){*(end + 1) = *end;--end;}//3.将val插入到vector中*pos = val;++_finish;//返回迭代器return pos;}
[erase()函数]
迭代器失效问题
删除的逻辑:
iterator erase(iterator pos){assert(pos >= _start && pos <= _finish);auto it = pos + 1;while (it != _finish){*(it - 1) = *it;++it;}--_finish;return pos;}
测试:
元素访问
[operation[]函数]
T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}
[迭代器]
iterator begin(){return _start;}iterator end(){return _finish;}const_itertator begin() const{return _start;}const_itertator end() const{return _finish;}
容量
[size()函数]
size_t size() const{return _finish - _start;}
[capacity()函数]
size_t capacity() const{return _end_of_storage - _start;}
代码
模拟实现vector的全部代码
#pragma once
#include<iostream>
#include<assert.h>
using std::cout;
using std::cin;
using std::endl;namespace zyy
{template<class T>class vector{typedef T* iterator;typedef const T* const_itertator;public://1.1默认构造vector():_start(nullptr),_finish(nullptr),_end_of_storage(nullptr){}//1.2 n个值构造 -- 这里使用匿名对象,是因为不知道要构造的对象是什么类型,vector(size_t n, const T& value = T()){resize(n, value);}//防止出现 非法的间接寻址 问题vector(int n, const T& value = T()){resize(n, value);}//1.3 用迭代器初始化template <class InputIterator> //这里使用模板的原因是可能有很多类型的迭代器,string,int, double等vector(InputIterator first, InputIterator last):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){while (first != last){push_back(*first);++first;}}//1.4 拷贝构造 -- 用v来初始化this//vector(const vector<T>& v)//{// //注意:不能使用memcpy,memcpy是浅拷贝// _start = new T[v.capacity()]; //开辟一块新的空间// for (size_t i = 0; i < v.size(); ++i)// {// _start[i] = v[i];// }// _finish = _start + v.size();// _end_of_storage = _start + v.capacity();//}// 拷贝构造vector(const vector<T>& v){_start = new T[v.capacity()]; //开辟一块和容器v大小相同的空间memcpy(_start, v._start, sizeof(T) * v.size());//将容器v当中的数据一个个拷贝过来_finish = _start + v.size(); //容器有效数据的尾_end_of_storage = _start + v.capacity(); //整个容器的尾}//vector(const vector<T>& v)//{// _start = v._start;// _finish = _start + v.size(); //容器有效数据的尾// _end_of_storage = _start + v.capacity(); //整个容器的尾//}//赋值运算符重载函数vector<T>& operator=(const vector<T> &v){//防止自己给自己赋值if (this != &v){//1.释放掉原来的空间delete[] _start;_start = new T[v.capacity()];for (int i = 0; i < v.size(); ++i){_start[i] = v[i];}_finish = _start + v.size();_end_of_storage = _start + v.capacity();}return *this;}~vector(){delete[] _start;_start = nullptr;_finish = nullptr;_end_of_storage = nullptr;}//迭代器iterator begin(){return _start;}iterator end(){return _finish;}const_itertator begin() const{return _start;}const_itertator end() const{return _finish;}//operator[]T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}//2.操作函数//2.1尾插void push_back(const T& val){if (_finish == _end_of_storage){int newCapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newCapacity);}*_finish = val;++_finish;}void pop_back(){assert(_finish >= _start);--_finish;}iterator insert(iterator pos, const T& val){assert(pos >= _start && pos <= _finish);//1.判断扩容逻辑if (_finish == _end_of_storage){//1.1计算出pos和_start的偏移量int n = _start - pos;int newCapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newCapacity);//1.2扩容完之后根据偏移量找到新pos的位置pos = _start + n;}//2.将pos后的内容往后移动auto end = _finish - 1; //_finish指向的是最后一个元素的下一个位置while (end >= pos){*(end + 1) = *end;--end;}//3.将val插入到vector中*pos = val;++_finish;//返回迭代器return pos;}iterator erase(iterator pos){assert(pos >= _start && pos <= _finish);auto it = pos + 1;while (it != _finish){*(it - 1) = *it;++it;}--_finish;return pos;}//2.2 扩容函数,将vector的容量扩大到nvoid reserve(size_t n){if (n <= capacity()){//不进行任何操作}else{//先将size()的内容存储下来int sz = size();//这里的扩容是开辟一块空间,将旧的内容拷贝的新空间上T* tmp = new T[n]; if (_start){for (int i = 0; i < size(); ++i){tmp[i] = _start[i];}//释放掉以前的空间delete[] _start;}//让_start指向新开辟的空间_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}}void resize(size_t n, const T& value = T()){if (n <= size()){_finish = _start + n;}else{//1.扩容reserve(n);//2.将内容插入到vector中while (_finish != _start + n){*_finish = value;++_finish;}}}size_t size() const{return _finish - _start;}size_t capacity() const{return _end_of_storage - _start;}void print(){for (int i = 0; i < size(); ++i){cout << _start[i] << " ";}cout << endl;}private:T* _start = nullptr;T* _finish = nullptr;T* _end_of_storage = nullptr;};
}
总结
在模拟实现vector中需要注意的地方:
-
拷贝构造函数必须使用深拷贝,不能使用
memcpy()
函数,因为memcpy()
函数是浅拷贝。浅拷贝对内置类型没有什么影响,但是对自定义类型,可能会导致析构两次的错误。 -
在对vector进行扩容时,主要的思想是开辟一块新的空间,然后将原来的空间的内容拷贝到新的空间中。需要重新计算
_finish
和_end_of_storage
,_finish = _start + size()
。 如果调用size()
函数就会导致访问出现问题。具体原因是size()函数的实现逻辑是_finish - _start
。 在扩容之后,_start
指向了新的空间,_finish
还在原来的空间,使用_finish - _start
会导致访问越界。因此解决办法就是在_start
指向新空间时先用sz
接收size()
的返回值,在后续修改_finish
时,就不会调用函数导致访问越界了。 -
当进行
insert()
插入时,可能会出现迭代器失效的问题。 主要原因是,在插入过程中,如果遇到扩容的情况,就会导致_start
指向了新的空间,但是传入的pos
还指向原来的空间,在扩容之后再进行插入,就会出现pos
访问越界。
做法和size()
是一样的,先保存一下pos
到_start
的偏移量,在_start
指向新空间之后,使用偏移量找到pos
在新空间的位置。 -
外部迭代器失效的问题。在进行插入或者删除值之后,如果不对原来的迭代器进行更新,并且再次访问该迭代器时,就会出现迭代器失效问题。具体表现在访问迭代器为随机值。
解决办法为:1.insert()和erase()函数都返回迭代器,并且在自己调用的时候接收迭代器(做到对迭代器的更新)。
相关文章:

【STL】vector模拟实现
vector引入 vector的实现主要依靠三个成员变量:start,finish和end_of_storage 其中: [start]指向容器中的起始位置 [finish]指向容器中最后一个有效数据的下一个位置 [end_of_storage]指向容器中现有容量的位置 通过这三个指针,就使得vector的size…...

静态成员static关键字
定义: 静态成员在C类中是一个重要的概念,它包括静态成员变量和静态成员函数。 静态成员变量 1定义:静态成员变量是类的所有对象共享的变量。与普通成员变量相比,无论创建了多少个类的实 例,静态成员变量只有一份拷贝…...

本地项目git同步到线上
将本地创建的项目同步到你的 GitHub 账号线上仓库,可以按照以下步骤进行操作: 1. 在 GitHub 上创建一个新仓库 登录你的 GitHub 账号。点击右上角的加号(),然后选择 New repository。填写仓库的名称、描述等信息。选…...

Allegro如何导入DXF结构文件并生成板框(1)?
在用Allegro进行PCB设计时,需要导入DXF结构文件,由此来生成PCB的板框。 本节先讲Allegro如何导入DXF结构文件?下节讲如何利用导入的DXF结构文件生成OUTLINE板框。 Allegro如何导入DXF结构文件并生成板框(2)?-CSDN博客 详细操作方法如下: 1、选择菜单栏File 选择Import…...

Word密码忘记怎么办?三个密码找回工具帮你轻松找回密码
在工作当中,为了保护文档内容的安全,我们时常会设置密码。但有时会因为长时间未打开而忘记了密码,导致word文档无法打开。面对这种情况,我们该怎么办呢?下面小编就将给大家带来3个实用的密码找回工具,帮助大…...

使用 ABP 框架 (ASP.NET Boilerplate Project) 创建一个带有迁移功能的示例
使用 ABP 框架 (ASP.NET Boilerplate Project) 创建一个带有迁移功能的示例项目是一个很好的方式来学习如何结合高级框架进行开发。ABP 框架提供了强大的模块化和分层架构,适合构建复杂的企业级应用程序。 以下是一个使用 ABP 框架的完整示例项目,它展示了如何创建一个包含 …...

WPF图表控件库
LiveCharts: LiveCharts2预览版、内存管理不是很好,长时间持续更新的情况下,内存溢出,慎用 数据加载量不能太大(1000点左右 开始卡) 第一步:下载LiveChart NuGet包 第二步:引用&a…...

JAVA-WEB资源配置
用JAVA进行编写WEB项目时,我们一般需要对WEB进行统一配置,例如制定拦截路径、页面解析器、跨域配置、fastjson报文解析、文件上传大小配置等。 Getter Setter Configuration public class WebConfiguration extends WebMvcConfigurationSupport {priva…...

分享一个基于微信小程序的宠物服务中心的设计与实现(源码、调试、LW、开题、PPT)
💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流&…...

时空自回归模型(STAR)及 Stata 具体操作步骤
目录 一、引言 二、文献综述 三、理论原理 四、实证模型 五、稳健性检验 六、程序代码及解释 附录 数据预处理 生成时空权重矩阵 一、引言 时空自回归模型(Spatial-Temporal Autoregressive Model,简称 STAR)在分析具有时空特征的数…...

SpringCloud集成XXL-JOB定时任务
项目场景: XXL-JOB是一个分布式任务调度平台,它能够帮助开发者轻松地实现任务的定时执行、任务调度和任务管理 接入步骤 下载XXL-JOB压缩包 链接: xxl-job XXL-JOB做为子模块 将压缩包解压,项目二级新建目录xxl-job,放入目录…...

《财经网》揭秘格行销量第一的秘籍!年销百万台,获千万级网红推荐!
随身WiFi已成为当下网红爆款神器,却为何频频陷入用户信任的危机?低价诱惑背后的限速陷阱、流量虚标,市场看似繁华,实则暗藏玄机。然而,就在这片混沌与质疑交织的迷雾中,一个品牌悄然崛起,以惊人…...

Java 中 Integer 类的比较行为
在 Java 中,Integer 类的比较行为有其特定的规则,这些规则涉及到缓存和对象比较。让我们分析一下你提供的代码: java public class test2_4 { public static void main(String[] args){Integer a 100;Integer b 100;Integer c 1000;Int…...

C# 通过反射(Reflection)调用不同名泛型方法
在C#中,通过反射调用泛型方法时,如果方法的名称或参数类型有所不同,那么你需要根据具体的情况来构造合适的MethodInfo对象。由于你提到的是调用“不同名”的泛型方法,这意味着你需要首先确定具体要调用的方法名,然后再…...

Spring Boot整合Drools入门:实现订单积分规则
文章目录 项目结构Maven配置配置Drools订单实体类订单积分规则测试规则总结 在开发过程中,我们经常遇到需要根据业务规则来进行决策的场景。比如,电商平台可能需要根据订单金额为用户添加相应的积分。为了灵活地处理这些业务规则,我们可以借助…...

【C语言】文件操作函数详解
目录 C语言文件操作函数详解表格汇总1. fopen2. fclose3. fread4. fwrite5. fseek6. ftell7. rewind8. fprintf9. fscanf10. feof11. ferror12. clearerr13. 总结14. 附录:函数参考表15. 结束语相关文章: C语言文件操作函数详解 C语言提供了一组标准库函…...

Java 垃圾回收,看一遍就懂
了解 Java 垃圾收集的工作原理并优化应用程序中的内存使用情况。详细了解 Java 中内存管理的复杂性。 垃圾收集是一个关键过程,可以帮助任何Java 开发公司。编程语言中的这一强大功能可以巧妙地管理内存分配和释放,防止内存泄漏并优化资源利用率。它就像…...

手把手教你CNVD漏洞挖掘 + 资产收集
0x1 前言 挖掘CNVD漏洞有时候其实比一般的edusrc还好挖,但是一般要挖证书的话,还是需要花时间的,其中信息收集,公司资产确定等操作需要花费一定时间的。下面就记录下我之前跟一个师傅学习的一个垂直越权成功的CNVD漏洞通杀&#…...

华为云低代码AstroZero技巧教学1:表格的超链接赋能
在低代码AstroZero的标准页面设计和构建上,我们总是在思考如何让用户体验能够更加流畅。 为此,我们特推出低代码AstroZero技巧教学系列合集,让各位开发者能够更加方便快捷地掌握低代码AstroZero的操作技巧。 本次技巧内容: 在As…...

https握手过程详解
https握手过程详解 上一篇《HTTPS通讯全过程》中https握手过程实际上还有更多的细节,为什么会这样设计呢?是因为一开始将握手过程时,吧步骤说的太详细会导致更难理解惹。所以我就先在上一篇把部分细节忽略,把原来几步的过程先简化…...

Lesson 63 Thank you, doctor
Lesson 63 Thank you, doctor 词汇 better a. 更好的 搭配:feel better get better 感觉好些了 成语:Better late than never. 晚做总比不做好。 Half a loaf is better than no bread. 有比没有好。…...

使用python和matlab实现BP神经网络算法的分析比较
分析和比较使用Python和MATLAB实现BP神经网络算法实现的复杂度、代码可读性、库支持、性能以及应用的灵活性等。 1. BP神经网络的基本原理 BP神经网络(Back Propagation Neural Network)是一种多层前馈神经网络,通过反向传播算法来训练网络。其基本思想是利用梯度下降法,…...

智慧卫生间环境传感器有哪些?智慧卫生间的特点@卓振思众
随着科技的进步和人们对生活品质的要求不断提高,智慧卫生间作为现代化设施的代表,越来越受到关注。智慧卫生间不仅仅是在外观设计上做文章,更在于其背后强大的智能系统,特别是环境传感器的应用,让厕所的管理和使用变得…...

智能分班结果自动发布系统
新学期,校园里又将迎来一批充满活力的新生。对于老师们来说,除了准备教学计划和课程内容,还有一项看似简单却颇为繁琐的任务——发布分班。传统的分班信息发布方式,通常是老师们一个个私信给学生家长,家长们收到信息后…...

vue 后台管理 指定项目别名
越多越好 文章目录 一、指定项目路径别名二、全局loading进度条实现三、动态页面标题的实现四、全局刷新 和 全屏 一、指定项目路径别名 在 vite.config.js 里配置 import path from "path"export default defineConfig({resolve:{alias:{"~":path.resol…...

【Python机器学习】FP-growth算法——构建FP树
在第二次扫描数据集时会构建一棵FP树。为构建一棵树,需要一个容器来保存树。 创建FP树的数据结构 FP树要比书中其他树更加复杂,因此需要创建一个类来保存树的每一个节点: class treeNode:def __init__(self,nameValue,numOccur,parentNode…...

JAVA itextpdf 段落自动分页指定固定行距打印
JAVA itextpdf 段落自动分页指定固定行距打印 前言:公司有个需求,打印的合同模板左上角要加上logo的图标。但是itext pdf 自动分页会按照默认的顶部高分页打印内容的,导致从第二页开始logo图标就会把合同的内容给覆盖掉了。然后尝试了挺多方法…...

基于SpringBoot+Vue的周边游平台个人管理模块的设计与实现
TOC springboot220基于SpringBootVue的周边游平台个人管理模块的设计与实现 第一章 绪论 1.1 选题背景 目前整个社会发展的速度,严重依赖于互联网,如果没有了互联网的存在,市场可能会一蹶不振,严重影响经济的发展水平…...

开源数据库同步工具monstache
Monstache是一个用Go语言编写的同步工具,主要用于将MongoDB中的数据同步到Elasticsearch中。它支持全量同步和增量同步,并提供了丰富的配置参数以及使用Go、JavaScript编写插件来自定义处理数据的逻辑的能力。Monstache 工作流程如下图: 以下…...

Ubuntu连接GitHub
报错:Please make sure you have the correct access rights and the repository exists.原因:本地没有SSH Key存在解决: 首先为系统设置github的用户名和自己的邮箱 git config --global user.name "****" git config --global us…...