c++之说_14|左值引用与右值引用

提起左右值引用我就头疼

左值:

1、在内存中开辟了空间的便叫左值

2、左值不一定可以赋值  如字符串常量

3、左值可以取地址

右值:

1、在内存中没有开辟空间的

2、右值无法取地址

如:

立即数(1,2,3)

函数返回值 直接返回非类型引用

Lvalue getT() { return Lvalue(); };
int get() { return c;  };

返回的这个int值或Lvalue类型对象就是一个右值 因为没有开辟空间

3、将亡值

什么叫将亡值  我的理解是一种标志 告诉说这个对象我要销毁

Lvalue&& getR();  函数返回值是右值引用 返回的这个对象 就叫将亡对象  即将销毁


Lvalue c;
static_cast<Lvalue&&>(c);  转换返回的操作数也叫将亡值

我的理解就是告诉我们 这个值是要销毁的  推荐使用一个新对象去存储

  什么叫左值引用? 其实就是 这个对象所代表的内存空间的另一个名字  在编译器内部

  本质上是指针实现的

   对左值引用取地址  所取的是引用对象的地址值

Lvalue d;//左值

const Lvalue& b2 = d;//绑定左值
Lvalue& b3 = d;//绑定左值

&b2 == &d;
&b3 == &d;

而右值引用 则引用的是右值

Rvalue r;//左值
Rvalue&& r1 = Rvalue();//绑定右值

//r1 是左值  有名的右值引用  为 左值
const Rvalue&& r2 = static_cast<Rvalue&&>(r1);//绑定右值(实际上是左值转换到右值)成将亡值

Rvalue&& r3 = static_cast<Rvalue&&>(r);

记住有名字的右值引用  是左值  所以可以取地址

std::cout << "r:" << &r << endl;
std::cout << "r1:" << &r1 << endl;
std::cout << "r2:" << &r2 << endl;
std::cout << "r3:" << &r3 << endl;

&r == &r3;
&r1 == &r2;

由于是引用  当然可以改变所引用的对象

struct Rvalue
{


};
struct Lvalue : public Rvalue
{
	int c;
	Lvalue() = default;
	Lvalue(int Inc) :c(Inc) {};

	Lvalue getT() { return Lvalue(); };
	Lvalue&& getR() { 
		auto c = new Lvalue(100);  
		return static_cast<Lvalue&&>(*c);
	};
	int get() { return c;  };
};
std::cout << "" << endl;
Lvalue op(50);
std::cout << "op.c:" << op.c << endl;
Lvalue& Lop = op;
Lop.c = 100;
std::cout << "左值引用修改"<< endl;
std::cout << "op.c:" << op.c << endl;
Lvalue& Rop = op;
Lop.c = 800;
std::cout << "右值引用修改" << endl;
std::cout << "op.c:" << op.c << endl;

这么一看左右值引用都是一样的感觉

他们主要体现在函数上

struct Lvalue : public Rvalue
{
	int c;
	int* p;
	Lvalue() = default;
	Lvalue(int Inc) :c(Inc), p(new int()) {};


	Lvalue& operator=(Lvalue& lc) 
	{ 
		c = lc.c;
		p = new int;
		*p = * lc.p;
		return *this; 
	};
	Lvalue& operator=(const Lvalue& lc) 
	{
		c = lc.c;
		p = new int;
		*p = *lc.p;
		return *this; 
	};
	Lvalue& operator=(Lvalue&& lc) 
	{
		c = lc.c;
		p = lc.p;
		lc.p = nullptr;
		return *this;
	};
	Lvalue& operator=(const Lvalue&& lc) 
	{	
		Lvalue&& Rc = const_cast<Lvalue&&> (lc);
		c = Rc.c;
		p = Rc.p;
		Rc.p = nullptr;

		return *this; 
	};


	Lvalue getT() { return Lvalue(); };
	Lvalue&& getR() { 
		auto c = new Lvalue(100);  
		return static_cast<Lvalue&&>(*c);
	};
	int get() { return c;  };
};

注意那几个 operator= 重载赋值运算符的函数

这其实就是所谓的 深拷贝  浅拷贝

//深拷贝
Lvalue& operator=(Lvalue& lc) 
{ 
	c = lc.c;
	p = new int;    //重新开辟了堆空间 
	*p = * lc.p;    //将 lc.p 中的int值 存入新开的堆空间中
	return *this; 
};

//浅拷贝
Lvalue& operator=(Lvalue&& lc) 
{
	c = lc.c;
	p = lc.p;        
//没有开辟新的堆空间  直接拿到 将亡值 lc 的 p所存储的内存地址  达到复用的目的
// 这也是他们所说的窃取资源
	lc.p = nullptr;
	return *this;
};
Lvalue& operator=(Lvalue& lc) 
{ 
	std::cout << "Lvalue& operator=(Lvalue& lc)" << endl;
	c = lc.c;
	delete p;
	p = new int;
	*p = * lc.p;
	return *this; 
};
Lvalue& operator=(const Lvalue& lc) 
{
	std::cout << "Lvalue& operator=(const Lvalue& lc)" << endl;
	c = lc.c;
	delete p;
	p = new int;
	*p = *lc.p;
	return *this; 
};
Lvalue& operator=(Lvalue&& lc) 
{
	std::cout << "Lvalue& operator=(Lvalue&& lc) " << endl;
	c = lc.c;
	delete p;
	p = lc.p;
	lc.p = nullptr;
	return *this;
};
Lvalue& operator=(const Lvalue&& lc) 
{	
	std::cout << "Lvalue& operator=(const Lvalue&& lc) " << endl;
	Lvalue&& Rc = const_cast<Lvalue&&> (lc);
	c = Rc.c;
	delete p;
	p = Rc.p;
	Rc.p = nullptr;

	return *this; 
};

调用处

Lvalue t1(100);
*t1.p = 80;
Lvalue t2(200);
*t2.p = 800;
std::cout << "" << endl;
std::cout << "初始化时" << endl;
std::cout << "t1.c:" << t1.c << endl;
std::cout << "t1.p:" << t1.p << endl;
std::cout << "*t1.p:" << *t1.p << endl;
std::cout << "" << endl;
std::cout << "t2.c:" << t2.c << endl;
std::cout << "t12.p:" << t2.p << endl;
std::cout << "*t2.p:" << *t2.p << endl;

std::cout << "" << endl;
std::cout << "t1 = t2" << endl;

t1 = t2;//Lvalue& operator=(Lvalue& lc) ;

std::cout << "t1.c:" << t1.c << endl;
std::cout << "t1.p:" << t1.p << endl;
std::cout << "*t1.p:" << *t1.p << endl;
std::cout << "" << endl;
std::cout << "t2.c:" << t2.c << endl;
std::cout << "t12.p:" << t2.p << endl;
std::cout << "*t2.p:" << *t2.p << endl;


std::cout << "" << endl;
std::cout << "t1 = static_cast<Lvalue&&>(t2)" << endl;

t1 = static_cast<Lvalue&&>(t2); 
//Lvalue& operator=(Lvalue&& lc)  如果没有  就考虑 Lvalue& operator=(const Lvalue&& lc)  
如果还没有 就调用Lvalue& operator=(const Lvalue& lc) 

std::cout << "t1.c:" << t1.c << endl;
std::cout << "t1.p:" << t1.p << endl;
std::cout << "*t1.p:" << *t1.p << endl;
std::cout << "" << endl;
std::cout << "t2.c:" << t2.c << endl;
std::cout << "t12.p:" << t2.p << endl;
//std::cout << "*t2.p:" << *t2.p << endl; //访问空指针是错误的

我们注释掉

/* Lvalue& operator=(Lvalue&& lc) 
{
	std::cout << "Lvalue& operator=(Lvalue&& lc) " << endl;
	c = lc.c;
	delete p;
	p = lc.p;
	lc.p = nullptr;
	return *this;
}; 
  */

Lvalue& operator=(const Lvalue&& lc) 
{	
	std::cout << "Lvalue& operator=(const Lvalue&& lc) " << endl;
	Lvalue&& Rc = const_cast<Lvalue&&> (lc);
	c = Rc.c;
	delete p;
	p = Rc.p;
	Rc.p = nullptr;

	return *this; 
};

看调用 Lvalue& operator=(const Lvalue&& lc) 

我们继续注释

/* Lvalue& operator=(Lvalue&& lc) 
{
	std::cout << "Lvalue& operator=(Lvalue&& lc) " << endl;
	c = lc.c;
	delete p;
	p = lc.p;
	lc.p = nullptr;
	return *this;
}; 
  */

/*
Lvalue& operator=(const Lvalue&& lc) 
{	
	std::cout << "Lvalue& operator=(const Lvalue&& lc) " << endl;
	Lvalue&& Rc = const_cast<Lvalue&&> (lc);
	c = Rc.c;
	delete p;
	p = Rc.p;
	Rc.p = nullptr;

	return *this; 
};
*/

看调用与结果

这就是右值引用存在的价值

告诉大家这个对象需要销毁  你怎么处理看你的了  

如果只用左值引用 无法很好的区分  因为cosnt lvalue&&  即可左值也可右值

你不知道传进来的这个对象是 const 修饰的对象  还是  要表示的销毁对象

我们也看到了引用是可以直接修改对象的  所以也是会有点问题  有些人不按照规则来

这样的函数 是有隐患的  我的本意是  这个返回值是即将销毁的值  然而外部可修改

Lvalue&& getR() { 
	auto c = new Lvalue(100);  
	return static_cast<Lvalue&&>(*c);
};

折叠引用  使用类型别名  using  typedef  即可达到折叠引用的目的

using ob = Lvalue&;
typedef Lvalue& ob1;
using ou = Lvalue&&;
typedef Lvalue&& ou1;

Lvalue k;
ob& o = k;//左值引用
ob && o1= k;//左值引用
ou& o2 = k;//左值引用
ou&& o3 = (Lvalue&&)k;//右值引用

折叠引用只有一个规则:

右值引用的右值引用 才是右值引用  其余都为左值引用

&& &&  右值引用

& && 左值引用

&& & 左值引用

& & 左值引用

而我们所知晓的 std::forward 完美转发  返回值就是  &&

用了点折叠引用

好了  到最后了 

我们说一下

空类 和 继承 一个空类 内存大小是什么样的

Lvalue d;//左值
Rvalue r;//左值
std::cout<<	sizeof(d)<<endl;//4   继承一个空类  空类所占的1字节被优化掉
std::cout << sizeof(r) << endl;//1

  写完了

对了知乎大佬的参考  左右值引用的要点  

(3 条消息) c++为什么要搞个引用岀来,特别是右值引用,感觉破坏了语法的简洁和条理,拷贝一个指针不是很好吗? - 知乎 (zhihu.com)

最后参考代码


struct Rvalue
{


};
struct Lvalue : public Rvalue
{
	int c;
	int* p;
	Lvalue() = default;
	Lvalue(int Inc) :c(Inc), p(new int()) {};


	Lvalue& operator=(Lvalue& lc) 
	{ 
		std::cout << "Lvalue& operator=(Lvalue& lc)" << endl;
		c = lc.c;
		delete p;
		p = new int;
		*p = * lc.p;
		return *this; 
	};
	Lvalue& operator=(const Lvalue& lc) 
	{
		std::cout << "Lvalue& operator=(const Lvalue& lc)" << endl;
		c = lc.c;
		delete p;
		p = new int;
		*p = *lc.p;
		return *this; 
	};
	/*Lvalue& operator=(Lvalue&& lc) 
	{
		std::cout << "Lvalue& operator=(Lvalue&& lc) " << endl;
		c = lc.c;
		delete p;
		p = lc.p;
		lc.p = nullptr;
		return *this;
	};*/
	/*Lvalue& operator=(const Lvalue&& lc) 
	{	
		std::cout << "Lvalue& operator=(const Lvalue&& lc) " << endl;
		Lvalue&& Rc = const_cast<Lvalue&&> (lc);
		c = Rc.c;
		delete p;
		p = Rc.p;
		Rc.p = nullptr;

		return *this; 
	};*/


	Lvalue getT() { return Lvalue(); };
	Lvalue&& getR() { 
		auto c = new Lvalue(100);  
		return static_cast<Lvalue&&>(*c);
	};
	int get() { return c;  };
};

int main(int line,   const char* arg[])
{
	Lvalue d;//左值
	Rvalue r;//左值
	std::cout<<	sizeof(d)<<endl;//4   继承一个空类  空类所占的1字节被优化掉
	std::cout << sizeof(r) << endl;//1

	//const 修饰的左值引用 既可以绑定左值又可以绑定右值     Lvalue() 右值  无名的
	const Lvalue& b = Lvalue();//绑定右值
	const Lvalue& b2 = d;//绑定左值
	Lvalue& b3 = d;//绑定左值
	
	Rvalue&& r1 = Rvalue();//绑定右值
	//r1 是左值  有名的右值引用  为 左值
	const Rvalue&& r2 = static_cast<Rvalue&&>(r1);//绑定右值(实际上是左值转换到右值)
	Rvalue&& r3 = static_cast<Rvalue&&>(r);
	
	//std::move(r);
	std::cout << "左值"<< endl;

	std::cout << "d:"<< & d << endl;
	std::cout << "b2:"<< &b2 << endl;
	std::cout << "b:" << &b << endl;
	std::cout << "b3:" << &b3 << endl;

	std::cout << "右值"<< endl;

	std::cout << "r:" << &r << endl;
	std::cout << "r1:" << &r1 << endl;
	std::cout << "r2:" << &r2 << endl;
	std::cout << "r3:" << &r3 << endl;
	
	//td::cout << "纯右值" << &Rvalue() << endl; //error
	//&d.getT();
	decltype(auto) v = d.getR();
	v.c = 50;
	std::cout << "v:" << &v << endl;
	
	auto str = "dadad";
	std::cout << "字符串:" << &"dadad" << endl;
	std::cout << "str:" << &str << endl;

	std::cout << "" << endl;
	Lvalue op(50);
	std::cout << "op.c:" << op.c << endl;
	Lvalue& Lop = op;
	Lop.c = 100;
	std::cout << "左值引用修改"<< endl;
	std::cout << "op.c:" << op.c << endl;
	Lvalue& Rop = op;
	Lop.c = 800;
	std::cout << "右值引用修改" << endl;
	std::cout << "op.c:" << op.c << endl;

	int&& i = 10;
	i = 80;

	
	
	Lvalue t1(100);
	*t1.p = 80;
	Lvalue t2(200);
	*t2.p = 800;
	std::cout << "" << endl;
	std::cout << "初始化时" << endl;
	std::cout << "t1.c:" << t1.c << endl;
	std::cout << "t1.p:" << t1.p << endl;
	std::cout << "*t1.p:" << *t1.p << endl;
	std::cout << "" << endl;
	std::cout << "t2.c:" << t2.c << endl;
	std::cout << "t12.p:" << t2.p << endl;
	std::cout << "*t2.p:" << *t2.p << endl;
	
	std::cout << "" << endl;
	std::cout << "t1 = t2" << endl;

	t1 = t2;//Lvalue& operator=(Lvalue& lc) ;
	
	std::cout << "t1.c:" << t1.c << endl;
	std::cout << "t1.p:" << t1.p << endl;
	std::cout << "*t1.p:" << *t1.p << endl;
	std::cout << "" << endl;
	std::cout << "t2.c:" << t2.c << endl;
	std::cout << "t12.p:" << t2.p << endl;
	std::cout << "*t2.p:" << *t2.p << endl;


	std::cout << "" << endl;
	std::cout << "t1 = static_cast<Lvalue&&>(t2)" << endl;
	
	t1 = static_cast<Lvalue&&>(t2); //Lvalue& operator=(Lvalue&& lc)  如果没有  就考虑 Lvalue& operator=(const Lvalue&& lc)  如果还没有 就调用Lvalue& operator=(const Lvalue& lc) 
	
	std::cout << "t1.c:" << t1.c << endl;
	std::cout << "t1.p:" << t1.p << endl;
	std::cout << "*t1.p:" << *t1.p << endl;
	std::cout << "" << endl;
	std::cout << "t2.c:" << t2.c << endl;
	std::cout << "t12.p:" << t2.p << endl;
	//std::cout << "*t2.p:" << *t2.p << endl; //访问空指针是错误的
	using ob = Lvalue&;
	typedef Lvalue& ob1;
	using ou = Lvalue&&;
	typedef Lvalue&& ou1;

	Lvalue k;
	ob& o = k;//左值引用
	ob && o1= k;//左值引用
	ou& o2 = k;//左值引用
	ou&& o3 = (Lvalue&&)k;//右值引用
	
	std::forward<Lvalue&&>(k);
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity类银河恶魔城学习记录7-1 P67 Sword Throw Skill State源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Sword_Skill.cs using System.Collections; using System.Collections.Gen…

nba2k24 韩旭面补

nba2k23-24 韩旭面补 nba2k23-nba2k24通用 韩旭面补 下载地址&#xff1a; https://www.changyouzuhao.cn/9605.html

【原创 附源码】Flutter安卓及iOS海外登录--Tiktok登录最详细流程

最近接触了几个海外登录的平台&#xff0c;踩了很多坑&#xff0c;也总结了很多东西&#xff0c;决定记录下来给路过的兄弟坐个参考&#xff0c;也留着以后留着回顾。更新时间为2024年2月7日&#xff0c;后续集成方式可能会有变动&#xff0c;所以目前的集成流程仅供参考&#…

Flex布局 (上万字)超详细讲解 这篇就够了

一、Flex概述 Flex布局&#xff0c;全称为“Flexible Box Layout”&#xff0c;意为“弹性盒布局”。它是一种现代的CSS布局模式&#xff0c;旨在提供一种更有效的方式来布局、对齐和分配容器中项目之间的空间&#xff0c;即使它们的大小未知或动态变化。 Flex布局的主要特点…

Unity类银河恶魔城学习记录6-2 P66 Clone‘s Attack源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Clone_Skill.cs using System.Collections; using System.Collections.Gen…

二叉搜索树删除操作的递归与非递归写法

如何进行删除操作 对于二叉搜索树的删除操作&#xff0c;主要分为以下3种情况讨论&#xff1a; 1、删除的结点没有左右孩子 2、删除的结点只有一个孩子 3、删除的结点有左右孩子 所以&#xff0c;我们将会用if…else…分为最多3种情况讨论&#xff08;实际上只分了两种&#x…

关于java的多线程初识

关于java的多线程初识 我们从今天开始&#xff0c;正式学习java的多线程&#xff0c;我们在前面的文章中学习到了java的基础&#xff0c; 但是距离我们工作实战还差的很远&#xff0c;我们学习好了基础&#xff0c;以后的文章会逐步的深入&#xff0c;去讲解各种前端框架&…

同余数论性质

同余概念 当 a%m b%m&#xff0c;说明a和b同余&#xff0c;写作若 a≡b(mod m) 性质 衍生出几条性质 1.m | abs(a-b)&#xff0c;即|a-b|是m的倍数。&#xff08;注意&#xff0c;0是任何数的倍数&#xff09; 2.当a≡b(mod m)&#xff0c;c≡d(mod m)&#xff0c; 有ac…

IDEA Ultimate下载(采用JetBrain学生认证)

IDEA Ultimate版本下载 Ulitmate是无限制版&#xff08;解锁所有插件&#xff0c;正版需要付费。学生可以免费申请许可&#xff09;Community是开源社区版本&#xff08;部分插件不提供使用&#xff0c;比如Tomcat插件。免费&#xff09; 我们将通过学生认证获取免费版。 Je…

【vue3学习笔记】shallowReactive与shallowRef;readOnly与shallowReadOnly;toRaw与markRaw

尚硅谷Vue2.0Vue3.0全套教程丨vuejs从入门到精通 课程 P158节 《shallowReactive与shallowRef》笔记&#xff1a; reactive()与shallowReactive()&#xff1a;reactive()处理后的数据是响应式的&#xff0c;对象内嵌套的深层结构全部是响应式的。shallowReactive()处理后的数据…

闭环控制系统手自动策略(车辆定速巡航应用)

闭环控制系统的手自动策略并不会完全一样&#xff0c;不同的行业&#xff0c;基于不同的规范和安全考虑给出的手自动策略是不一样的&#xff0c;这里我们介绍汽车行业定速巡航应用。 PID闭环控制系统手自动切换的相关文章&#xff0c;还可以查看下面链接&#xff1a; 无扰切换…

2013-2022年上市公司迪博内部控制指数、内部控制分项指数数据

2013-2022年上市公司迪博内部控制指数、分项指数数据 1、时间&#xff1a;2013-2022年 2、范围&#xff1a;上市公司 3、指标&#xff1a;证券代码、证券简称、辖区、证监会行业、申万行业、内部控制指数、战略层级指数、经营层级指数、报告可靠指数、合法合规指数、资产安全…

基于Locust实现MQTT协议服务的压测脚本

一、背景简介 业务背景大概介绍一下&#xff0c;就是按照国标规定&#xff0c;车辆需要上传一些指定的数据到ZF的指定平台&#xff0c;同时车辆也会把数据传到企业云端服务上&#xff0c;于是乎就产生了一些性能需求。 目前我们只是先简单的进行了一个性能场景的测试&#xf…

C++进阶(十五)C++的类型转换

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、C语言中的类型转换二、为什么C需要四种类型转换三、C强制类型转换1、static_cast2、reint…

中国电子学会2019年12月份青少年软件编程Scratch图形化等级考试试卷三级真题(选择题、判断题)

一、单选题(共 25 题&#xff0c;每题 2 分&#xff0c;共 50 分) 1.怎样修改图章的颜色&#xff1f;&#xff08; &#xff09; A. 只需要一个数字来设置颜色 B. 设置 RGB 的值 C. 在画笔中设置颜色、饱和度、亮度 D. 在外观中设置或修改角色颜色特效 2.以下程序的执…

2024年Midjourney 付费订阅流程 | Midjourney 各版本介绍,使用虚拟信用卡支付买Midjourney流程指南

1.Midjourney介绍 Midjourney 是一款备受欢迎的人工智能生成图像工具&#xff0c;它可以通过输入文字描述&#xff0c;自动生成精美的图像。与许多其他图像生成工具不同&#xff0c;Midjourney 不需要安装任何软件&#xff0c;也不受个人电脑性能的限制&#xff0c;因为它运行…

计算机毕业设计SSM基于的冷链食品物流信息管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; vue mybatis Maven mysql5.7或8.0等等组成&#xff0c;B…

微信小程序(四十二)wechat-http拦截器

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.wechat-http请求的封装 2.wechat-http请求的拦截器的用法演示 源码&#xff1a; utils/http.js import http from "wechat-http"//设置全局默认请求地址 http.baseURL "https://live-api.ith…

【学网攻】 第(26)节 -- 综合网络实验一

系列文章目录 目录 系列文章目录 文章目录 前言 一、综合实验 二、实验 1.引入 实验目标 实验设备 实验拓扑图 实验配置 文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节…

C++ //练习 6.5 编写一个函数输出其实参的绝对值。

C Primer&#xff08;第5版&#xff09; 练习 6.5 练习 6.5 编写一个函数输出其实参的绝对值。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /*************************************************************************&…
最新文章