Java基础语法

Java是完全面向对象,安全可靠,与平台无关的语言。

Java的版本有:

JavaEE(J2EE)企业版:为开发企业环境下的应用程序提供的一套解决方案

J2SE标准版(基础版):开发普通桌面和商务应用程序

J2ME小型版:针对电子消费产品和嵌入式设备提供的解决方案

环境变量:

        在运行Java程序前,需要先配置环境变量,将Java中的.exe文件配置到path中,方便在Java中各个工具的运行。程序运行时,需要配置classpath,将.class文件配置到classpath,告知虚拟机到该路径下寻找。

JRE:Java运行环境。

JDK:Java开发工具包。为开发人员提供,其中也包括JRE。

JVM:Java虚拟机,用于运行Java程序。

        Java言由关键字、标识符、注释、常量与变量、运算符、语句、函数与数组组成。

第一部分:关键字

        Java中的关键字是Java中定义的具有特殊意义的单词(小写)。包括权限修饰符,类、方法及变量修饰符,程序流程控制语句,基本数据类型,void,异常处理,包相关等。(在相关的章节会重点介绍)

第二部分:标识符

1、标识符是在程序中自定义的一些名词。

2、由26个英文字母(大小写),数字:0-9,符号:_$组成。

3、定义合法标识符的规则。

a、数字不可以开头。

b、不可以使用关键字。

4、Java中严格区分大小写,在起名时,为了提高阅读性,要尽量有意义。

注意:main不是关键字,main函数是程序的入口,能被虚拟机识别。


总结:Java中的名称规范

1、包名:xxyyzz(多个单词组成时,所有字母小写)。

2、类名及接口名:XxxYyyZzz(多个单词组成时,所有单词首字母大写)。

3、变量名或函数名:xxxYyyZzz(多个单词组成时,第一个单词首字母小写,其余单词字母大写)。

4、常量名:XXX_YYY_ZZZ(多个单词组成时,所有单词字母均大写,两个单词间用"_"连接)。

第三部分:注释

注释用于调试程序或者注解代码。注释分为以下三种:

         注意事项:

1、  多行注释中可以加单行注释,但是不能加多行注释。

2、  文档注释用于生成API文档。

3、  写代码时尽量养成写注释的习惯。(包括要求、思路、步骤及功能等)

第四部分:常量

1、  常量表示不能被改变的值。

2、  Java中常量的分类:

1)  整数常量:所有整数。

2)  小数常量:所有小数。

3)  布尔型常量:较为特殊,只有两个值:true false

4)  字符常量:将一个数字、字母或者符号用单引号 ’ ’ 标识。

5)  字符串常量:将一个或者多个字符用双引号 “ ” 标识。

6)  null常量:只有一个数值:null。

对于整数,Java有三中表现形式:

         十进制:0-9,满10进1;

         八进制:0-7,满8进1,用0开头;

         十六进制:0-9,A-F,满16进1,用0x开头。

二进制:

        二进制由电信号(开关,1与0)演变而来,任何数据在计算机中都是以二进制的形式存在的,一个整数在内存中一样也是二进制的,但是使用一大串的1或者0组成的数字使用很麻烦,于是就将一大串数字缩短,变出现了八进制、十六进制。

进制转换:

十进制与二进制之间的转换:

9的二进制表现形式:余数倒着写,为1001。

二进制1001转换为10进制:

二进制与八进制之间的转换:(3个二进制位表示1位)

二进制与十六进制之间的转换:(4个二进制位表示一位)

负数的二进制表现形式:正数的二进制取反加1。如-6的二进制:


第五部分:变量

         用于存储同类型的不确定的数。

         格式:

                   数据类型 变量名 = 初始化值;

         Java是强类型的语言,对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的空间存储。

数据类型:

1、 基本数据类型:

数值型:整数(byte,short,int,long)、浮点数(float,double)

字符型:char

布尔型:boolean

2、 引用数据类型:

类(class)

接口(interface)

数组([])

 各类型数据所占内存

Java中存在着强类型转换: 

如:byte b = 3;

         b = b+2;//报错,等号右边强制提升为int型

         b = (byte)(b+2);//将int型数据强转为byte

注意:float与int类型数据做运算时,结果为float类型,因其精度高。

 

第六部分:运算符

1、 算数运算符

注意:当有负数参与%运算时,结果只看被模数的符号。

2、 赋值运算符

注意:byte b = 4;

             b = b+2;//报错

             b += 2;//正确,为一个运算符

3、 逻辑运算符


注意:

||与|的区别:

|两边都参与运算;||左边为true右边不参与运算。

&&与&的区别:

&两边都参与运算;&&左边为false时右边不参与运算。

4、 位运算符

注意:

1)>>与>>>的区别:

>>:右移时最高位是什么就补什么(如负数最高位补1)。

>>>:无论最高位是什么都补零。

2)一个数异或一个数两次,结果为原来的数。

交换两个数的值的方法:

1)通过第三方变量,如:

int m = 6,n = 7;
int temp;

temp = m;
m=n;
n=temp;

2)不通过第三方变量

int m=7,n=8;

n=m+n;
m=n-m;
n=n-m;

3)异或的方式

int m=4,n=7;

n=n^m;
m=n^m;
n=n^m;

示例代码:

/*
需求:演示位运算符
*/
class Demo1 
{
	public static void main(String[] args) 
	{
		//定义一个int类型的变量
		int num = 60;
		//与运算
		int n1=num&15;
		
		//将结果强转为char类型
		System.out.println((char)(n1-10+'A'));
		//右移运算
		int temp = num>>4;
		System.out.println(temp);
	}
}

运算结果为:

图解:

5、 三元运算符

格式:(条件表达式)?表达式1:表达式2

如果条件为true,则结果为表达式1。

如果条件为false,则结果为表达式2。

6、 转义字符

注意:

1)在Windows系统中,回车符由\r\n组成。

2)要想得到\,在输入时需要输入\\。

 

第七部分:程序流程控制

一、判断结构

格式1:
if(条件表达式)
{
	执行语句;
}

格式2:
if(条件表达式)
{
	执行语句;
}else
{
	执行语句;
}

格式3:
if(条件表达式)
{
	执行语句;
}else if(条件表达式)
{
	执行语句;
}
... ...
else
{
	执行语句;
}

总结:

1、if/else结构简写格式:三元运算符,变量 = (条件表达式)?表达式1:表达式2

2、三元运算符可以简化代码,但因其是一个运算符,必须要有结果。

package demo;

/*
需求:演示if与三元运算符
*/
class Demo1 
{
	public static void main(String[] args) 
	{
		//调用指定的函数
		ifDemo();
		arichDemo();
	}
	//if演示
	public static void ifDemo(){
		int x=6;
		if(x==6){
			System.out.println("x = "+6);
		}else{
			System.out.println("x = "+x);
		}
	}
	//三元运算符演示。二者等效
	public static void arichDemo(){
		int x = 7,y;
		y = (x==7)?7:x;
		System.out.println("y = "+y);
	}
}

结果为:

二、选择结构

格式:
switch(表达式){
	case 取值1:
		执行语句;
		break;
	case 取值2:
		执行语句;
		break;

	... ...
	default
		执行语句;
		break;
}

switch语句的特点:

1、  被选表达式只接受4中类型:byte,int,short,char。

2、  switch语句中case与default没有顺序,但执行顺序是固定的,即先执行case,再执行default。

3、  switch语句可以以break和}结束。

4、  如果匹配的case或者default没有对应的break,那么程序就会继续向下执行,不再判断case,并运行可以执行的语句,直到遇到break或switch语句结尾结束。

5、多个case可以对应同一个执行语句。

示例代码:

/*
	需求:switch 语句演示
*/
class SwitchDemo
{
	public static void main(String[] args)
	{
		int x=1;
		switch(x)
		{
			//多个选项对应同一条输出语句
			case 3:
			case 4:
			case 5:
				System.out.println(x+"春季");
				break;
			case 6:
			case 7:
			case 8:
				System.out.println(x+"夏季");
				break;
			case 9:
			case 10:
			case 11:
				System.out.println(x+"秋季");
				break;
			case 12:
			case 1:
			case 2:
				System.out.println(x+"冬季");
				break;
			default:
			<span style="white-space:pre">	</span>break;	
		}
	}
}

swith与if的区别:

1、  if除了能判断数值外,还可以判断区间;switch判断区间很麻烦。

2、  对于运算结果为boolean的,if能判断,switch不能。

        因此,对具体数值进行判断,并且数值不多时,且类型符合byte,short,int,char时,可以使用switch完成。其他情况用if。

 

三、循环结构(遍历)

循环有while循环、do/while循环和for循环,依次介绍。

1、while循环:

格式1:while循环
while(条件表达式){
	执行语句:
}

格式2:do/while循环
do{
	执行语句:
}while(条件表达式)

注意:

1)while的特点:先判断循环条件,只有条件满足再执行循环体。

2)do/while的特点:先执行循环体,在判断条件,只有条件满足再继续执行循环体。

也就是说do/while的循环体至少会执行一次。

2、for循环:

for循环语句格式:
for(初始化表达式;条件表达式;循环后的操作表达式){
	执行语句;
}

for与while的区别:

1)for语句中的变量作用域为当前for循环,不能在for循环外面使用该变量。

2)for循环中的循环条件表达式必须要有真假结果。

        因此,当变量仅仅由于控制循环次数,作为循环增量存在,用for语句更合适(内存更优化);用while语句时,循环结束后变量仍然存在,其仍占用内存。(本质上两者可以直接互换)

示例代码:

/*
需求:while循环、do/while循环与for循环演示
*/
public class Demo2 {
	public static void main(String[] args){
		//调用指定的函数
		whileDemo();
		doWhileDemo();
		forDemo();
	}
	public static void whileDemo(){
		int x = 0;
		//while循环
		while(x<4){
			if(x==3){
				System.out.println("x = "+x);
				//跳出当前循环
				break;
			}
			x++;
		}
	}
	public static void doWhileDemo(){
		int y = 0;
		//do while循环(循环体至少执行一次)
		do{
			System.out.println("y = "+y);
		}while(y>3);
	}
	public static void forDemo(){
		//for循环
		for(int z=0;z<=3;z++){
			System.out.print(z+" ");
		}
		//System.out.println(z);编译报错,变量不存在
	}
}

运行结果为:

无线循环的最简单的表现形式:

for(;;){}

while(true){}


累加思想:

        使用循环,并通过一个变量记录数据的状态变化后的结果,这就是累加思想。

/*
 * 需求:求1+2+...+100的和
 * 
 * 思路:
 * 典型的累加思想,定义一个计数器记录数据的变化,通过for循环来控制变化。
 */
public class CountDemo{
	public static void main(String[] args){
		int sum = getSum(100);
		System.out.println("sum = "+sum);
	}

	private static int getSum(int num) {
		//计数器
		int sum = 0;
		for(int x=0;x<=num;x++){
			sum = sum+x;
		}
		return sum;
	}
}

结果:

3、循环嵌套

所谓循环嵌套就是循环中还有循环,这在java中很常见。

/*
需求:打印如下图形
*
**
***
****
*****

思路:
1、输出矩阵,采用for循环嵌套的形式
2、外循环控制行,内循环控制列(5行5列)
3、列数在随着外循环的变化而变化,改变循环条件,让其随之改变。
*/
public class Demo3 {
	public static void main(String[] args){
		for(int x=0;x<5;x++){
			for(int y=0;y<=x;y++){
				System.out.print("*");//不换行
			}
		<span style="white-space:pre">	</span>//一行结束再换行
			System.out.println();
		}
	}
}

小规律:

1)输出图形的尖朝上,可以改变内循环条件,让条件随着外循环变化。

2)尖朝下,可以改变内循环初始化值,让初始化值随着外循环变化。

示例代码:

package demo;
/*
需求:输出九九乘法表

思路:
1、与上一题类似,采用forfor循环嵌套的形式,改变内循环的循环条件,让其随着外循环的变化而变化。
2、输出结果成了两个数的成绩。
*/
public class Demo4 {
	public static void main(String[] args){
		for(int x=1;x<=9;x++){
			for(int y=1;y<=x;y++){
				//输出x*y,并加入制表符优化格式
				System.out.print(x+"*"+y+"="+x*y+"\t");
			}
			System.out.println();
		}
	}
}
输出结果:

4、其他流程控制语句

1)break:应用于选择结构和循环结构。

2)continue:应用于循环结构。

注意:

1)这两个语句离开应用范围是没有任何意义的。

2)这两个语句单独存在时,下方不可以有语句,因为执行不到。

3)continue语句表示结束本次循环,继续下次循环;break是跳出当前循环。

4)标号的出现,可以让两个语句左右于指定的范围。(标号只能用于循环上)

class  Demo
{
	public static void main(String[] args) 
	{
		//w循环
		w:for(int x=0;x<5;x++)
		{
			//q循环
			q:for(int y=0;y<3;y++)
			{
				if(y==2)
				{
					//跳出break循环
					break w;
				}
				System.out.print("*");
			}
			System.out.println();
		}
	}
}


第八部分:函数

一、函数的定义

函数就是定义在类中的具有特定功能的一段独立小程序。其格式如下:

修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,... ...)
{
	执行语句;
	return 返回值;
}
返回值类型:函数运行后的结果的数据类型
参数类型:形式参数的数据类型
形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数
实际参数:传递给形式参数的具体数值
return:用于结束函数
返回值:返回给调用者的值

注意:

1、一般函数只有被调用才会执行,且函数必须写在类里面。

2、函数中只能调用函数,不能在函数内部定义函数。

3、定义函数时,函数的结果应返回给调用者,让调用者进行处理。

二、函数的特点

1、定义函数可以将功能代码进行封装。

2、便于对该功能进行复用。

3、函数只有被调用才会执行。

4、函数的出现提高了代码的复用性。

5、若函数中没有具体的返回值,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。


三、函数的应用

        函数是java中最小的功能单元,在写代码时要先将功能封装在函数中,什么时候需要该功能,调用即可,主函数中尽量不要写过多的代码。

如果定义函数?

1、明确需要实现的功能。

2、明确返回值类型。

3、明确参数列表。


四、函数的重载

1、重载的概念

在同一个类中,允许存在两个以上的同名函数,只要它们的参数个数或参数类型不同即可。

2、重载的特点

与返回值类型无关,只看参数列表。(参数有顺序之分)。

3、重载的好处

方便于阅读,优化了代码。

当定义的功能相同,但是参与运算的未知内容不同时,则定义同一个函数名称以表示其功能,方便阅读,而通过参数列表的不同来区分不同的函数。

4、重载示例

/*
需求:利用函数的重载特性,定义多个功能用于打印不同类型的数据
*/
public class Demo5 {
	public static void main(String[] args){
		//调用指定的函数
		print();
		print(5);
		print(7,9.23);
	}
	//定义函数用于输出abc
	public static void print(){
		System.out.println("abc");
	}
	//定义函数用于输出int 型数据
	public static void print(int num){
		System.out.println("num = "+num);
	}
	//定义功能用于数据int 与 double 型数据
	public static void print(int a,double b){
		System.out.println("a = "+a+"b = "+b);
	}
}

第九部分:数组

一、数组的定义

数组就是同一种类型数据的集合,它是一个容器。

数组可以自动给数组中的元素从0开始编号,方便操作这些元素。

数组的格式:

格式1:
元素类型[] 数组名 = new 元素类型[元素个数或数组的长度]
示例:int[] arr = new int[6];

格式2:
元素类型[] 数组名 = new 元素类型[]{元素1,元素2,...};
示例:int[] arr = new int[]{3,4,5};
      int[] arr = {3,4,5};

二、数组的内存分配及特点

1、内存结构

        Java程序在运行时,需要在内存中开辟空间,为了提高运算效率,对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

栈内存(栈区):

用于存储局部变量(定义在for循环、函数、方法参数中的变量均为局部变量)。

栈内存的特点:内存自动是释放(数据使用完毕后)

堆内存(堆区):

用于存储数组和对象,通过new建立的实体都存在与堆内存中。

堆内存的特点:

内存地址值、默认初始化值、垃圾回收机制。

Java垃圾回收机制:

        程序员不用手动清除垃圾,只要对象或实体在内存中变成垃圾,JVM就会自动启动垃圾回收机制,将堆内存中的不再被使用的实体清除掉(不定时)。

方法区、本地方法区、寄存器

示例:

class ArrayDemo{
	public static void main(){
		int[] arr = new int[3];//新建一个长度为2的int类型数组
	}
}

代码在内存中的体现:

三、数组操作常见问题

1、角标越界异常。操作数组时,访问到了数组中不存在的角标。(编译时并不会报错)

2、空指针异常。当引用没有任何指向(null)时,该引用还在操作实体。

四、数据常见操作

数组中有一个属性可以获取到数组中元素的个数,即 数组名.length

在操作数组时,通常会用到for循环对数组进行遍历。

1、选择排序

package demo;
/*
需求:对数组进行选择排序。
选择排序:选择一个固定位置和其他位置进行比较,符合条件就交换(最值出现在头角标位)
*/
public class ArrayDemo1 {
	public static void main(String[] args){
		int[] arr ={6,3,2,9,5}//定义一个数组
		print(arr);
		//对数组进行排序
		selectSort(arr);
		//打印排序后的数组
		print(arr);
		
	}
	//功能:对数组进行选择排序
	public static void selectSort(int[] arr) {
		for(int x=0;x<arr.length-1;x++){//-1避免角标越界
			for(int y=x+1;y<arr.length;y++){
				//arr[x]>arr[y]就交换
				if(arr[x]>arr[y])
					swap(arr,x,y);
			}
		}
	}
	//功能:交换数组中两个元素的位置
	public static void swap(int[] arr,int a,int b){
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}
	//功能:输出数组
	public static void print(int[] arr){
		System.out.print("[");
		//对数组进行遍历,以获取元素
		for(int x=0;x<arr.length;x++){
				if(x!=arr.length-1)
					System.out.print(" "+arr[x]+",");
				else
					System.out.print(" "+arr[x]);
		}
		System.out.println(" ]");
	}
}

结果为:

图解:

2、冒泡排序

package demo;
/*
需求:对数组进行冒泡排序。
冒泡排序:相邻连个函数进行比较,符合条件就换位(最值出现在最后一位)
*/
public class ArrayDemo2 {
	public static void main(String[] args){
		int[] arr = {3,9,6,2,4};
		//输出数组
		print(arr);
		//对数组进行排序
		bubbleSort(arr);
		print(arr);
		
	}
	//功能:对数组进行冒泡排序
	public static void bubbleSort(int[] arr) {
		for(int x=0;x<arr.length-1;x++){//-1避免角标越界
			for(int y=0;y<arr.length-1-x;y++){//-x代表每次少比一个元素
				//相邻两个元素比较
				if(arr[y]>arr[y+1])
					swap(arr,y,y+1);
			}
		}
	}
	//功能:交换数组中两个元素的位置
	public static void swap(int[] arr,int a,int b){
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}
	//功能:输出数组
	public static void print(int[] arr){
		System.out.print("[");
		for(int x=0;x<arr.length;x++){
				if(x!=arr.length-1)
					System.out.print(" "+arr[x]+",");
				else
					System.out.print(" "+arr[x]);
		}
		System.out.println(" ]");
	}
}

排序后结果为:

图解:

注意:

选择排序与冒泡排序在数据较多时,处理效率较低。

实际开发中采用java.util.Array类进行操作。

3、折半查找

package demo;
/*
需求:对有序数组进行折半查找。
前提:数组有序

思路:
1、将需要查找的值key与中间角标的值arr[mid]进行比较。
	若key>arr[mid],则将小角标min移动到中间角标+1
	若key<arr[mid],则将大角标max移动到中间角标-1
	
2、当key==arr[mid],说明找到值,角标为中间角标
     当min>max,说明没有找到,返回-1
*/
public class ArrayDemo3 {
	public static void main(String[] args){
		int[] arr = {3,4,7,9,10};
		printArr(arr);
		
		//分别查找7和8在数组中存在的位置
		int index1 = halfSearch(arr,7);
		int index2 = halfSearch(arr,8);
		
		System.out.println("index1 = "+index1+"\r\nindex2 = "+index2);
	}
	public static int halfSearch(int[] arr, int key) {
		//定义两个角标,头角标为0,尾角标为最大角标
		int max = arr.length-1;
		int min = 0;
		
		//获取中间角标
		int mid = (max+min)/2;
		//当中间角标对应的值不是索要查找的值时
		while(key!=arr[mid]){
			if(key>arr[mid])
				min = mid+1;//key比中间值大,小角标=min+1
			else if(key<arr[mid])
				max = mid-1key//比中间值小,大角标=min-1
			//循环一次就改变一次中交角标
			mid = (max+min)/2;
			
			if(min>max){
				return -1;//未找到,返回-1
				//return mid//返回key插入的位置
			}	
		}
		//其他情况说明key==arr[min],返回中间角标
		return mid;
	}
	public static void printArr(int[] arr) {
		System.out.print("[");
		for(int x=0;x<arr.length;x++){
			if(x==arr.length-1)
				System.out.println(arr[x]+"]");
			else	
				System.out.print(arr[x]+", ");
		}
	}
}
运行结果:

图解:

注意:若要在有序数组中插入元素,则返回的角标-1应为mid。

五、二维数组

1、定义及格式

格式1:int[][] arr = new int[3][4];
含义:
	1)定义一个名称为arr的二维数组。
	2)二维数组中有3个一维数组。(二维数组的长度为3)
	3)每一个一维数组中有4个元素。
	4)一维数组的名称为arr[0],arr[1],arr[2]

格式2:int[][] arr = new int[2][];
含义:
	1)二维数组中有2个一维数组。
	2)每个一维数组的初始化值为null。
	3)可以对这2个一维数组进行初始化:

	arr[0] = new int[3];
	arr[1] = new int[5];

格式3:int[][] arr = {{3,2,4},{2,1},{5,7,1}};
含义:
	1)二维数组中有3个一维数组。
	2)三个一维数组分别为{3,2,4},{2,1},{5,7,1}
arr.length()为二维数组的长度,arr[0].length()为二维数组中第1个元素的长度
 
 

2、内存中的体现

六、数组的综合利用(查表法)

/*
 *  查表法完成进制转换。
 *  
 *  思路:
 *  1、通过分析发现,进制的转换其实就是相对应的数进行&运算然后右移指定的位数,依次循环,直到最后的数为0
 *     每次循环都会得到一个索引。
 *  2、可以定义一个字符数组0-9,A-F,然后利用索引取查该表。
 *  3、最后当得到的字符反向输出即可。
 *  
 *  步骤:
 *  1、定义一个功能来实现进制转换
 *  2、在该函数中定义一个字符数组(表,0-9,A-F)
 *  3、定义一个字符串缓冲区用于存储查表后所得到的数据
 *  4、对数进行遍历,在循环中进行不断的&基数和右移运算,获取指针并查表,并将查到的数字存入字符串缓冲区中
 *  5、对字符串缓冲区中的数据进行输出。
 */
public class ChangeRadix {
	public static void main(String[] args) {
	
		toBin(6);
		toHex(60);
		
	}
	//转换成16进制
	public static void toHex(int num) {
	
		changeRadix(num, 15, 4);
	}
	//转换成2进制
	public static void toBin(int num) {

		changeRadix(num,1,1);
	}
	//进制转换共同代码
	private static void changeRadix(int num,int base,int offset){
		//表格
		char[] chs = {'0','1','2','3','4','5','6','7',
					  '8','9','a','b','c','d','e','f'};
		
		//字符串缓冲区,用于存储数据
		StringBuilder sb = new StringBuilder();
		while(num!=0){
			//获取每一段数据,并使用该数据取查表
			int pos = num&base;
			sb.append(chs[pos]);
			num = num>>>offset;
		}
		System.out.println(sb.reverse());
	}

}
运行结果为:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值