C++入门(上)

文章目录

  • 1:什么是C++
  • 2.C++的发展史
  • 3:C++关键字(C++98)
  • 4:命名空间
    • 4.1:命名空间的概念
    • 4.2:命名空间的定义
    • 4.3:命名空间的使用
      • 4.3.1加命名空间的名称以及域作用限定符
      • 4.3.2:使用using将命名空间中某个成员引入
      • 4.3.3:使用using namespace +命名空间名称展开命名空间
        • 代码1
        • 代码2
  • 5:C++输入与输出
    • 代码1
    • 代码2
  • 6:缺省参数
    • 6.1:缺省参数概念
    • 6.2:缺省参数分类
      • 6.2.1:全缺省参数
      • 6.2.2:半缺省参数
  • 7:函数重载
    • 7.1:函数重载概念
    • 7.2:函数重载的分类
      • 7.2.1:参数类型不同
      • 7.2.2:参数的个数不同
      • 7.2.3:参数的顺序不同

嘿嘿,家人们,从今天开始我们将进入C++的学习,在C++这块呢,博主不讲和C语言重合的语法,所以如果对C语言不是很熟悉的话, 可以去看看博主C语言滴博客,好啦,废话不多讲,接下来我们开始进入C++的学习!

1:什么是C++

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

2.C++的发展史

1979年,贝尔实验室的本贾尼等人试图分析unix内核的时候,试图将内核模块化,于是在C语言的基础上进行扩展,增加了类的机制,完成了一个可以运行的预处理程序,称为C with classes。
编程语言的发展史和我们日常打游戏时打怪升级一样,也是不断地逐步递进,由浅入深的过程。下面是C++的历史版本.

在这里插入图片描述

C++还在不断地向后发展,博主在这里主要是以C++98与C++11为主,因为公司主流使用的还是C++98与C++11,将C++98与C++11掌握好以后,随着对C++的理解不断加深,uu们有时间可以去琢磨更新的特性。

3:C++关键字(C++98)

简单了解了C++这门面向对象的编程语言后,接下来,我们来看一下C++的关键字,C++总计有63个关键字,C语言总共32个关键字.
PS:下面只是让uu们看一下C++有多少关键字,不对关键字进行具体的讲解,有些关键字在C语言阶段就已经见过了,对于那些没有见过的,等后面博主会给uu们进行细讲的.

在这里插入图片描述

4:命名空间

在讲命名空间以前,我们首先来看下面这段代码。
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int x = 5;
int main()
{
    int x = 25;
    printf("%d\n", x);
    //访问的是全局变量x
    printf("%d\n",::x);
    return 0;
}

这段代码我定义了两个变量x,一个是全局变量x,一个是局部变量x,C语言阶段博主讲过,如果全局变量和局部变量的变量名冲突了,那么在访问的时候是优先访问局部变量,但是这个时候如果非要访问这个全局变量x那应该怎么办呢?在C++中我们则可以使用域作用限定符::来访问这个全局变量x.域作用限定符在不指定域的情况下默认为全局作用域

在这里插入图片描述

4.1:命名空间的概念

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

我们首先来看下面这段代码。
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int rand = 5;
int main()
{
    printf("%d", rand);
    return 0;
}

在这里插入图片描述

这段代码的报错提示是说rand以前定义的是函数,我们知道在C语言阶段,rand是一个库函数,需要包含头文件<stdlib.h>,在C++中我们为了避免命名冲突和名字污染,则提出了命名空间的概念.

4.2:命名空间的定义

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

#include <stdio.h>
namespace area1
{
	int rand = 25;
}

namespace area2
{
	int rand = 30;
	int Add(int value1,int value2)
	{
		return value1 + value2;
	}
}

int main()
{
	int result = area2::Add(25, 30);
	printf("%d\n", area1::rand);
	printf("%d\n", area2::rand);
	printf("%d\n", result);
	return 0;
}

在这里插入图片描述

一个命名空间就相当于定义了一个新的作用域,命名空间中的所有内容都局限于此命名空间中.在命名空间中我们可以定义变量/函数/类型等,如果说我们访问某个命名空间里面的成员,则需要使用::(域作用限定符)来指定域,然后跟上变量名来进行访问.此时我们再使用变量rand去命名时发现编译器不会报错了,因为将其锁定在了一个新的作用域,并且使用域作用限定符来指定域去进行访问了.

namespace area1
{
	struct Node
	{
		struct Node* next;
		int value;
	};
}
int main()
{
	//命名空间中结构体的使用
	struct area1::Node* Head;
	return 0;
}

PS:使用命名空间中的结构体跟使用命名空间中的变量与函数是有些不一样滴,这里uu们要稍微注意下。

除此之外,在同一个工程中允许存在多个相同名称的命名空间,编译器最后会将其合成在同一个命名空间中,我们看下面这段代码.

#pragma once
namespace area1
{
	int Add(int value1, int value2)
	{
		return value1 + value2;
	}
}
#include "List.h"
namespace area1
{
	struct Node
	{
		struct Node* next;
		int value;
	};
	int Add(int value3, int value4)
	{
		return value4 + value3;
	}
}
int main()
{
	//命名空间中结构体的使用
	struct area1::Node* Head;
	return 0;
}

在这里插入图片描述

博主在头文件List.h与test.cpp这个文件中都定义了Add函数并且命名空间使用了同一个名字,并且在test.cpp这个文件中包含了头文件List.h,这个时候我们运行这段代码会发现编译器给我们报错了,这是因为编译器将两个同样名称的命名空间合并在了一起,这个时候就出现了两个一模一样的函数,我们在C语言阶段讲过,一个工程中是不能出现两个一模一样的函数滴,所以编译器这里给我们进行了报错.

4.3:命名空间的使用

在命名空间中,我们可以定义变量、函数、结构体、类型等等,那么我们该如何去使用呢?以下三种方法可以帮助我们去使用命名空间里头的数据.

4.3.1加命名空间的名称以及域作用限定符

第一种方式呢就是通过域作用限定符+命名空间的名称来指定访问此命名空间中的数据.我们看下面这段代码.

#include <stdio.h>
namespace area1
{
	int value1 = 1;
	struct Node
	{
		struct Node* next;
		int value;
	};
	int Add(int value3, int value4)
	{
		return value4 + value3;
	}
}
int main()
{
	//命名空间中结构体的使用
	struct area1::Node* Head;
	area1::value1 = 25;
	printf("%d\n", area1::value1);
	return 0;
}

在这里插入图片描述

通过域作用限定符::,左边跟上命名空间的名称,右边则跟上该命名空间中的变量名来进行访问.

4.3.2:使用using将命名空间中某个成员引入

第二种方式则是使用using关键字将命名空间中的某个成员进行引入,这个时候我们就能直接进行访问了,不需要指定域了,我们看下面这段代码.

#include <stdio.h>
namespace area1
{
	int value1 = 1;
	struct Node
	{
		struct Node* next;
		int value;
	};
	int Add(int value3, int value4)
	{
		return value4 + value3;
	}
}
//使用using关键字将命名空间area中的进行进入
using area1::value1;
int main()
{
	//命名空间中结构体的使用
	struct area1::Node* Head;
	area1::value1 = 30;
	printf("%d\n", area1::value1);
	printf("%d\n",value1);
	return 0;
}

在这里插入图片描述

上面的代码中,当使用using关键字将命名空间area中的变量value1引入了以后,这个时候我们再去访问,就不需要指定域啦,可以直接进行访问.

4.3.3:使用using namespace +命名空间名称展开命名空间

第三种方式则通过使用using namespace + 命名空间名称展开命名空间来引入命名空间中的数据.

#pragma once

namespace QNodearea
{
	struct QNode
	{
		struct QNode* Node;
		int value;
	};
	int value = 30;
}
#pragma once
namespace Listarea
{
	struct List
	{
		struct List* Node;
		int value;
	};
	int value = 25;
}
代码1
#include <stdio.h>
#include "List.h"
//展开命名空间,拿到使用权限
using namespace Listarea;
int main()
{
	struct List* Node1;
	printf("%d", value);
	return 0;
}

在这里插入图片描述

在上述代码中,通过使用using namespace + 命名空间的名称展开命名空间,此时我们就能直接访问此命名空间中的数据了.

我们再来看下面这段代码

代码2
#include <stdio.h>
#include "List.h"
#include "QNode.h"
//展开命名空间,拿到使用权限
using namespace Listarea;
using namespace QNodearea;
int main()
{
	struct List* Node1;
	value;
	return 0;
}

此时我将命名空间Listarea,与QNodearea都进行了展开,此时我们再去使用value这个变量,看看会发生什么事?

在这里插入图片描述

很明显,此时编译器发生了报错,说不确定此value是Listarea中还是QNodearea中的,这个时候我们如果通过域作用限定符指定了域来进行访问的话,还会不会报错呢?

在这里插入图片描述

我们可以看到当我们指定了域以后此时编译器不发生报错,那这是为什么呢?原因在于编译器的搜索原则遵循以下规则:
不指定域:(1):先去当前的局部作用域搜索 (2):全局作用域搜索
指定域:若指定了域、就会直接去域里面进行搜索.
这也就是为什么当我们展开了两个命名空间,此时再去访问value那个变量会发生报错.

5:C++输入与输出

在C语言中有输入scanf与输出printf,在C++中同样也有滴哦!那么接下来我们来看看C++中的输入与输出.

代码1

#include <iostream>
using namespace std;
int main()
{
	cout << "hello world" << endl;
	return 0;
}

在这里插入图片描述

这段代码就是C++版本的hello world,uu们可能对此有些小疑惑,我们一步步地来看.
1:使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
2:std是C++标准库的命名空间名,C++标准库的定义实现都放到这个命名空间中.
3:cout和cin全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在< iostream >头文件中.
4:
<<是流插入操作符,>>是流提取运算符

代码2

#include <iostream>
using namespace std;
int main()
{
	int a;
	double b;
	char c;

	cin >> a;
	cin >> b >> c;

	cout << "a = " << a <<endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
	return 0;
}

在这里插入图片描述

这段代码就是C++滴输入方式。
1:使用C++输入输出更方便相较于C语言,不需要像printf/scanf输入输出时那样子手动控制格式,C++的输入输出可以自动识别变量类型。
PS:关于cout和cin还有很多复杂的用法,例如控制浮点数输出精度,控制整形输出格式等等,由于C++兼容C语言的用法,这些用法用得不是很多,因此博主在这里就不细讲啦.

6:缺省参数

6.1:缺省参数概念

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

#include <iostream>
using namespace std;
//a为缺省参数
void Function(int a = 35)
{
	cout << a << endl;
}

int main()
{
	Function();
	Function(20);
	return 0;
}

在这里插入图片描述

在上述代码中,我调用了两次Function函数,第一次调用没有进行传参,第二次调用进行了传参,由于我第一次调用未进行传参,因此在输出变量a时使用了a的缺省值,第二次调用进行了实参的传递,因此使用指定实参.

6.2:缺省参数分类

了解了缺省参数的概念后,接下来博主将详细介绍缺省参数的分类.

6.2.1:全缺省参数

#include <iostream>
using namespace std;
//a为缺省参数
void Function(int a = 35,int b = 25,int c = 35)
{
	cout <<"a = " << a << endl;
	cout <<"b = " << b << endl;
	cout <<"c = " << c << endl;
}

int main()
{
	Function();
	cout << endl;
	Function(20,40);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

在上述代码中,博主给每一个形参都赋予了缺省值,当形参全部都被赋予了缺省值,这时就是全缺省参数.并且在调用时,第一次调用未进行传参,因此形式参数使用的是缺省值,第二次调用只进行了部分传参,传参时,从左往右进行匹配,因此对于传递了实参的参数,则使用指定的实参,未传递实参的参数,则使用缺省值.
PS:传参时,不可跳跃传递哦!

6.2.2:半缺省参数

#include <iostream>
using namespace std;
void Function(int a,int b = 25,int c = 35)
{
	cout <<"a = " << a << endl;
	cout <<"b = " << b << endl;
	cout <<"c = " << c << endl;
}

int main()
{
	Function(20);
	cout << endl;
	Function(20,30);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

在上述代码中,只对部分参数使用了缺省值,因此被称为半缺省参数,半缺省参数要遵从一个规则即:**必须从右往左依次来给出,不能够间隔着给.**除此之外缺省参数还有以下几个注意点.

  1. 缺省参数不能函数声明和定义中同时出现如果声明和定义位置同时出现缺省参数,那么编译器就无法确定到底该用哪个缺省值.
    在这里插入图片描述

上面的图片中,声明和定义都出现了缺省值,此时程序运行时会发生报错,因为编译器无法确定该使用哪个缺省值.二者非要指定的话,只能在声明中出现,而不是在定义中出现.

2.缺省值必须是常量或者全局变量.
3.C语言不支持缺省参数.

7:函数重载

在自然语言中,一个词有多重含义,人们可以通过上下文来判断该词的真实含义,即该词被重载了,那么在这种场景下,我们来了解函数重载.

7.1:函数重载概念

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

7.2:函数重载的分类

7.2.1:参数类型不同

#include <iostream>
using namespace std;
int Function(int value1,int value2)
{
	cout << "int Add(int value1,int value2)" << endl;
	return value1 + value2;
}

double Function(double value1,double value2)
{
	cout << "double Add(doublue value1,double value2)" << endl;
	return value1 + value2;
}

int main()
{
	int Iresult = Function(2, 5);
	double Dresult = Function(2.5, 9.52);
	cout << Iresult << endl;
	cout << Dresult << endl;
	return 0;
}

在这里插入图片描述

上述代码中定义了两个一模一样的函数名,但是这两个函数的形参的参数类型不同,因此构成了函数重载.

7.2.2:参数的个数不同

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

//2.参数的个数不同
void Func()
{
    cout << "Func()" << endl;
}

void Func(int a)
{
    cout <<"Func(int a) " << a << endl;
}

int main()
{
    Func();
    Func(5);
    return 0;
}

在这里插入图片描述

这段代码也同样定义两个相同的函数名,但是这两个函数的参数的个数不同,因此也构成了函数重载.

7.2.3:参数的顺序不同

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

void Function(int value1,char str1)
{
    cout << value1 << " " << str1 << endl;
}

void Function(char str1,int value1)
{
    cout << str1 << " " << value1 << endl;
}

int main()
{
    Function(1, 'a');
    Function('a',1);
    return 0;
}

在这里插入图片描述

这段代码同样定义两个相同的函数名,但是这两个函数的参数的顺序不同,参数的顺序不同,其本质是参数的类型不同,因此也构成了函数重载.

PS:如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分.
在这里插入图片描述

好啦,家人们,关于C++入门(上)这块的相关细节知识,博主就讲到这里了,如果uu们觉得博主讲的不错的话,请动动你们滴滴的小手给博主点个赞,你们滴鼓励将成为博主源源不断滴动力!

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

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

相关文章

React Native开发iOS实战录

文章目录 背景环境准备主要工具xcode安装安装CocoaPods 基本步骤常见问题ruby3在macOS上编译失败import of module ‘glog.glog.log_severity’ appears within namespace ‘google’yarn网络问题pod安装失败unable to open settings file 相关链接 背景 准备将之前的一个Reac…

【复现】大华 DSS SQL 注入漏洞_46

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 大华DSS是大华的大型监控管理应用平台&#xff0c;支持几乎所有涉及监控等方面的操作&#xff0c;支持多级跨平台联网等操作。 可…

python+django咖啡网上商城网站

全网站共设计首页、咖啡文化、咖啡商城、个人信息、联系我们5个栏目以及登录、注册界面&#xff0c;让用户能够全面的了解中国咖啡咖啡文化宣传网站以及一些咖啡知识、文化。 栏目一首页&#xff0c;主要放置咖啡的起源及发展进程的图文介绍&#xff1b;栏目二咖啡文化&#xf…

BKP寄存器与RTC实时时钟

BKP寄存器 BKP寄存器简介 BKP&#xff08;Backup Registers&#xff09;备份寄存器 BKP可用于存储用户应用程序数据。当VDD&#xff08;2.03.6V&#xff09;电源被切断&#xff0c;他们仍然由VBAT&#xff08;1.83.6V&#xff09;维持供电。当系统在待机模式下被唤醒&#xf…

python高校实验室管理系统的django设计与实现81txp

技术栈 后端&#xff1a;python 前端&#xff1a;vue.jselementui 框架&#xff1a;django Python版本&#xff1a;python3.7 数据库&#xff1a;mysql5.7 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyCharm .本高校实验室管理系统采用python语言、MySQL数据库&…

每日五道java面试题之java基础篇(六)

第一题&#xff1a;Java 创建对象有哪⼏种⽅式&#xff1f; Java 中有以下四种创建对象的⽅式: new 创建新对象通过反射机制采⽤ clone 机制通过序列化机制 前两者都需要显式地调⽤构造⽅法。对于 clone 机制,需要注意浅拷⻉和深拷⻉的区别&#xff0c;对于序列化机制需要明…

Java 集合、迭代器

Java 集合框架主要包括两种类型的容器&#xff0c;一种是集合&#xff08;Collection&#xff09;&#xff0c;存储一个元素集合&#xff0c;另一种是图&#xff08;Map&#xff09;&#xff0c;存储键/值对映射。Collection 接口又有 3 种子类型&#xff0c;List、Set 和 Queu…

一键打造属于自己漏扫系统

0x01 工具介绍 本系统是对Web中间件和Web框架进行自动化渗透的一个系统,根据扫描选项去自动化收集资产,然后进行POC扫描,POC扫描时会根据指纹选择POC插件去扫描,POC插件扫描用异步方式扫描.前端采用vue技术,后端采用python fastapi。 0x02 安装与使用 1、Docker部署环境 编译…

git revert回退某次提交

请直接看原文: 【git revert】使用以及理解&#xff08;详解&#xff09;_git revert用法-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- 前言 试验得知:用Reset HEAD方…

MySQL基本操作之数据库的操作

一.创建数据库 1.基本语法 create database 数据库名&#xff1b; 注意别忘记加分号。 2.if not exists 数据库名字是唯一的&#xff0c;所以不可以创建已存在的数据库&#xff0c;如下&#xff1a; 重复创建就会报错 所以有了if not exists这个语法&#xff0c;加上之后&…

【大厂AI课学习笔记】【1.6 人工智能基础知识】(3)神经网络

深度学习是机器学习中一种基于对数据进行表征学习的算法。观测值(例如一幅草莓照片)可以使用 多种方式来表示&#xff0c;如每个像素强度值的向量&#xff0c;或者更抽象地表示成一系列边、特定形状的区域等。 深度学习的最主要特征是使用神经网络作为计算模型。神经网络模型 …

FAST角点检测算法

FAST&#xff08;Features from Accelerated Segment Test&#xff09;角点检测算法是一种快速且高效的角点检测方法。它通过检测每个像素周围的连续像素集合&#xff0c;确定是否为角点。以下是 FAST 角点检测算法的基本流程&#xff1a; FAST 角点检测算法的基本过程主要包括…

C++ //练习 5.12 修改统计元音字母的程序,使其能统计以下含有两个字符的字符序列的数量:ff、fl和fi。

C Primer&#xff08;第5版&#xff09; 练习 5.12 练习 5.12 修改统计元音字母的程序&#xff0c;使其能统计以下含有两个字符的字符序列的数量&#xff1a;ff、fl和fi。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /****…

【Spring学习】Spring Data Redis:RedisTemplate、Repository、Cache注解

1&#xff0c;spring-data-redis官网 1&#xff09;特点 提供了对不同Redis客户端的整合&#xff08;Lettuce和Jedis&#xff09;提供了RedisTemplate统一API来操作Redis支持Redis的发布订阅模型支持Redis哨兵和Redis集群支持基于Lettuce的响应式编程支持基于JDK、JSON、字符…

【Android】使用Android Studio运行Hello World项目

文章目录 1. JDK的安装与配置2. Android Studio的安装3. 运行Hello World项目3.1 新建项目3.2 修改项目配置3.2.1 修改UI界面3.2.2 配置 Android SDK 3.3 添加并运行虚拟设备3.4 运行项目 1. JDK的安装与配置 想要使用Android Studio&#xff0c;必须先配置Java环境&#xff0…

ArcGIS学习(七)图片数据矢量化

ArcGIS学习(七)图片数据矢量化 通过上面几个任务的学习,大家应该已经掌握了ArcGIS的基础操作,并且学习了坐标系和地理数据库这两个非常重要且稍微难一些的专题。从这一任务开始,让我们进入到实战案例板块。 首先进入第一个案例一一图片数据矢量化。 我们在平时的工作学…

自然语言处理(NLP)—— 基本概念

自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能和语言学领域的一个分支&#xff0c;它涉及到计算机和人类&#xff08;自然&#xff09;语言之间的相互作用。它的主要目标是让计算机能够理解、解释和生成人类语言的数据。NLP结…

Solidworks:平面草图练习

继续练习平面草图&#xff0c;感觉基本入门了。

如何在 Windows 上恢复已删除的 Excel 文件

许多公司和个人在 Excel 电子表格中保存有价值的信息。当会议需要某个重要的 Excel 文件时&#xff0c;突然意识到您已删除或丢失该文件可能会造成严重问题。不用担心。我们将向您展示在 Windows 计算机上恢复已删除的 Excel 文件的多种方法。 如何在 Windows 上恢复已删除的 E…

腾讯云4核8G服务器可以用来干嘛?怎么收费?

腾讯云4核8G服务器适合做什么&#xff1f;搭建网站博客、企业官网、小程序、小游戏后端服务器、电商应用、云盘和图床等均可以&#xff0c;腾讯云4核8G服务器可以选择轻量应用服务器4核8G12M或云服务器CVM&#xff0c;轻量服务器和标准型CVM服务器性能是差不多的&#xff0c;轻…