【初识C语言(下篇)】

💖 技术宅,拯救世界!

🎁作者:@ecember
🎁专栏:《从0开始——C语言》
🎁 对读者的话:相信奇迹的人本身和奇迹一样伟大

Alt


🌹感谢大家的点赞关注 🌹,如果有需要可以看我主页专栏哟💖


⚡10.前言

前面我们的C语言已经学到数组这里啦,今天我们继续来深度认识一下C语言,上一篇博客链接:初识C语言——上篇(以下内容均在vs2022中编译哦)。💖
在这里插入图片描述

⚡11.操作符

我们这里先来简单介绍一下操作符。

🌠11.1 算术操作符

在这里插入图片描述

🌀11.1.1 ‘/’操作符

其中+ - *和我们数学中的运算符一模一样。这里我们重点介绍/(除)和 %(取余)符。

int main()
{
	int a = 7 / 2;
	
	printf("%d\n", a);
	
	return 0;
}

根据数学的逻辑,它的输出是不是应该是3.5啊——非也,非也
在这里插入图片描述
相信已经有友友已经注意到了想输出小数是不是应该用浮点型啊,我们再试试。

int main()
{
	float a = 7 / 2;
	printf("%f\n", a);
	
	return 0;
}

在这里插入图片描述

这里的输出结果也只是换了个包装,只不过是多加了几个浮点零而已,这里我们不禁会想到是不是操作符‘/’的问题。是不是这个操作符关注的是整数除法,当俩边操作数有浮点数类型输出才会是浮点数。我们不妨一试。

int main()
{
	float f = 7 / 2.0;
	printf("%f\n", f);

	//7 / 2.0;

	return 0;
}

在这里插入图片描述
这里验证了我们的猜想。对于整数,我们的‘/’是向0取整的,那么对于负数是如何取整的呢?

int main()
{
	int a = -7 / 2;
	printf("%d\n", a);
	
	return 0;
}

在这里插入图片描述

对于负数,此操作符也是向0进行取整的。

🌀11.1.2 ‘%’操作符

‘%’操作符的基本功能是对取除法后的余数

int main()
{
	int a = 7 % 2;
	//商2余1,故输出1
	
	printf("%d\n", a);

	return 0;
}

在这里插入图片描述

’%‘两端操作数必须是整形,若输入浮点数即为非法操作,编译器会报错。

那么负数的取余操作呢?
在这里插入图片描述

负数的取余操作和正数基本一样。

🌀11.1.3 小科普1

上述实例输出都是浮点型数,那么怎么保留小数位数呢?

int main()
{
	float a = 7 / 2.0;

	printf("%.2f", a);

	return 0;
}

在这里插入图片描述

对于float型,我们只需要在输出函数%.nf,其中n表示保留n位小数。

int main()
{
	double a = 7 / 2.0;

	printf("%.2lf", a);

	return 0;
}

在这里插入图片描述

对于double型,我们只需要在输出函数%.nlf,其中n表示保留n位小数。

下面我们再来看看特殊案例——%e%g;

int main()
{

	printf("%e\n", 0.00001234);
	printf("%e", 0.0000001234);

	return 0;
}

在这里插入图片描述

这是C语言的科学计数法,e-05表示1.234000*10的5次方。

int main()
{
	printf("%g\n", 0.00001234);

	printf("%g\n", 0.0001234);

	return 0;
}

在这里插入图片描述

这里同样是使用%g来打印,结果却不一样,这是因为 %g表示以%f%e中较短的输出宽度输出单,双精度实数,在指数小于-4或者大于等于精度时使用%e格式

🌀11.1.4 小科普2

既然我们前面说到了取整方式,那么是否只有一种取整方式或者有没有什么取整函数呢?——当然是有的。
trunc-取整函数

#include<math.h>//后面不再书写,友友们需要注意哦
int main()
{
    printf("%f\n", trunc(-1.9));//-1
    printf("%f\n", trunc(1.9));//1
}

在这里插入图片描述

这里的trunc函数会将数字的小数部分直接去掉,只保留整数部分,不管数字是正数还是负数。需要注意的是trunc函数返回值为 %f,用整型会导致数据错误。

floor-地板取整

int main()
{
	printf("%.lf\n", floor(-1.9));//-2
	printf("%.lf\n", floor(-1.1));//-2
	printf("%.lf\n", floor(1.9));//1
	printf("%.lf\n", floor(1.1));//1
	return 0;
}

floor函数返回值为%lf型,我们保留到整数部分。
在这里插入图片描述

这里我们发现不论是 -1.9 还是 1.1都向比自己的方向取整,由此这个函数floor也就叫地板取整也叫 -∞取整

ceil-天花板取整

int main()
{
	printf("%.lf\n", ceil(-1.9));
	printf("%.lf\n", ceil(-1.1));
	printf("%.lf\n", ceil(1.9));
	printf("%.lf\n", ceil(1.1));

	return 0;
}

ceil函数返回值为%lf型,我们保留到整数部分。
在这里插入图片描述

这个函数恰好和floor相反,它总是向的方向取整,因此被戏称为天花板取整,也可以总结为 +∞取整

round-四舍五入取整

int main()
{
	printf("%.lf\n", round(-1.9));
	printf("%.lf\n", round(-1.1));
	printf("%.lf\n", round(1.9));
	printf("%.lf\n", round(1.1));

	return 0;
}

这里返回值同样是%lf.
在这里插入图片描述

这个函数就是我门熟悉的四舍五入啦,对于负数也是一样。

🌠11.2 移位操作符

在这里插入图片描述
右移操作符与左移操作符——以后讲解。

🌠11.3 位操作符

在这里插入图片描述

&——按位与
|——按位或
^——按位异或

以后讲解。

🌠11.4 赋值操作符

在这里插入图片描述

int main()
{
	int a = 10;//赋值并初始化

	//a = a + 5;
	a += 5;
	//a = a - 5;
	a -= 5;
	//a = a * 5;
	a *= 5;
	//a = a / 5;
	a /= 5;
	
	return 0;
}

我们挑了几个来讲,实际上赋值操作符视为了便于操作而设计的。

🌠11.5 单目操作符

在这里插入图片描述

🌀11.5.1 ‘!’操作符

C语言中0——假,非0——真,但我们默认1表示真。

int main()
{
	int a = 10;
	int b = 0;

	if (a)
		printf("hehe\n");
	if (!b)
		printf("haha\n");

	return 0;
}

在这里插入图片描述
这里本来b的值为0,if条件语句判断应该为假,但加入了 操作符,故判断题由假变为真,打印出haha。

🌀11.5.2 ‘±’操作符

这个操作符很简单我们浅讲一下。

int main()
{
	int a = 10;
	printf("%d\n", +a);//10
	printf("%d\n", -a);//-10

	return 0;
}

🌀11.5.3 ‘sizeof’操作符

这个操作符我们之前细细讲解过了,见链接【初识C语言(上篇)——数据类型】

int main()
{
	int a = 10;
	char c = 'w';
	int arr[10] = { 0 };

	//sizeof是一个操作符,不是函数
	printf("%zu\n", sizeof(a));
	printf("%zu\n", sizeof a);
	printf("%zu\n", sizeof(int));
	printf("%zu\n", sizeof(c));
	printf("%zu\n", sizeof c);
	printf("%zu\n", sizeof (char));
	
	//计算数组大小
	int sr = sizeof(arr) / sizeof(arr[0]);
	printf("%d", sr);

	return 0;
}

此处我们辨析一下strlen与sizeof。

strlen是库函数,只能针对字符串,求字符串的长度,即计算字符串中\0之前的字符个数
sizeof是操作符,是计算所占内存空间的大小

🌀11.5.4 ‘++ - -’操作符

int main()
{
	int a = 10;
	int b = ++a;//前置++,先++,后使用
	//a=a+1,b=a;
	printf("a=%d b=%d\n", a, b);//11 11

	int c = 10;
	int d = c++;//后置++,先使用,再++
	//d = c, c = c + 1;
	printf("c=%d d=%d\n", c, d);

	return 0;
}

在这里插入图片描述

🌊小练习
在这里插入图片描述
答案如下
在这里插入图片描述

🌀11.5.5 ‘强制转换’操作符

int main()
{
	int a = (int)3.14;//强转为int类型

	printf("%d\n", a);

	return 0;
}

在这里插入图片描述

🌠11.6 关系操作符

在这里插入图片描述
这里我们只讲最后两个。

int main()
{
	int a = 3;
	int b = 3;
	if (a != b)
		printf("hehe\n");
	if (a == b)
		printf("haha\n");
		
	return 0;
}

在这里插入图片描述

这里需要注意的是我们在实际写代码的过程中容易把 === 搞混,前一个判断相等,后一个是赋值运算符

🌀11.6.1 免死金牌

这里教大家一个写法,当遇到要判断某个变量是否等于一个数时

int main()
{
	int a = 10;

	if (10 == a)
	{
		printf("haha\n");
	}

	return 0;
}

这样写的话编译器在你少写一个等号的时候会报错,如图
在这里插入图片描述
而如果直接写,编译器就不会报错,它会当成你在赋值,不管是否相等都会输出。
在这里插入图片描述

🌀11.6.2 字符串“撞脸”

我门先来判断两个字符串是否相等。

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	
	if (arr1 == arr2)
	{
		printf("haha\n");
	}

	return 0;
}

在这里插入图片描述

咦,这是怎么回事?——显然我们不能用==来判断字符串是否相等。

这里我们要用上一个函数strcmp

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	
	if (strcmp (arr1,arr2) == 0)
	{
		printf("haha\n");
	}

	return 0;
}

在这里插入图片描述
注意

1.两个字符串是不能用双等号来判断相等的,需要用用strcmp来判断。
2.int 类型 char 类型 可以用双等号来比较。

🌠11.7 逻辑操作符

在这里插入图片描述

int main()
{

	int a = 0;
	int b = 5;
	int c = a && b;//假——0
	int d = a || b;//真——1
	
	printf("%d\n", c);//0

	if (a && b)//假
	{
		printf("hehe\n");//不打印
	}
	
	
	printf("%d\n", d);//1
	
	if (a || b)//真
	{
		printf("haha\n");//打印
	}

	return 0;
}

在这里插入图片描述

1. && -逻辑与–并且
2. || -逻辑或–或者
3. 逻辑操作符结果只能为1——真,0-——假

🌠11.8 条件操作符

在这里插入图片描述
条件操作符其实跟我们的用条件语句判断很像。

int main()
{
	int a = 4;
	int b = 0;
	
	if (a > 5)
	   b = 3;
	else
	   b = -3;

	printf("%d\n", b);//-3

	return 0;
}

我们知道打印出来是-3,那如果用条件操作符呢?

int main()
{
	int a = 4;
	int b = 0;
	
	//表达式
	b = (a > 5 ? 3 : -3);//两种写法都可以
	//(a > 5) ? (b = 3) : (b = -3);

	printf("%d\n", b);

	return 0;
}

在这里插入图片描述

这岂不是和我们的条件语句异曲同工之妙。

🌠11.9 逗号表达式

在这里插入图片描述

int main()
{
	int a = 3;
	int b = 5;
	int c = 0;
	int d = (a += 2, b = b - c + a, c = a + b);
	        //a=5    b=10           c=5+10
	
	printf("%d\n", d);//15

	return 0;
}

在这里插入图片描述

逗号表达式的特点:
从左往右依次计算,整个表达式的结果是最后一个表达式的结果

🌠11.10 千奇百怪表达式

这里我们主要科普下标引用函数调用结构成员(后面讲)
在这里插入图片描述

下标引用

int main()
{
	int arr[10] = { 0 };
	arr[4] = 5;
	printf("%d\n", arr[4]);
	
	return 0;
}

arr和4是[ ]的两个操作数
例:2+3 3+2
2和3是+的操作数

函数调用

int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int c = Add(2, 3);
	printf("c=%d\n", c);

	return 0;
}

()是函数的调用操作符,操作数是:Add,2,3

⚡12.关键字

C标准中共有32个关键字,而C99之后又增加了五个关键字,本次我们先来了解了解。

🌠12.1 关键字大杂烩

1.关键字是直接可以使用的
2.变量名不能是关键字

🌀12.1.1 数据类型关键字(12个)

关键字符号作用
char声明字符型变量或函数
short声明短整型变量或函数
int声明整型变量或函数
long声明长整型变量或函数
signed声明有符号类型变量或函数
float声明单精度浮点型变量或函数
double声明双精度浮点型变量或函数
unsigned声明无符号整形变量或函数
struct声明结构体变量或函数
union声明共用(联合)体数据类型
enum声明枚举类型
void声明函数无返回值或无参数,声明无类型指针

🌀12.1.2 控制语句关键字(12个)

关键字符号作用控制类型
forfor循环语句循环语句
do表示执行do...while中的循环体
whilewhile循环体
continue跳出本次循环,执行下一次循环
break跳出整个循环语句
if条件语句条件语句
else条件语句否定部分
goto无条件跳转语句
switch开关语句主体 开关语句
case开关语句分支
default开关语句其它分支(通常在最后)
return函数返回语句 返回语句

🌀12.1.3 存储类型关键字(5个)

关键字符号作用
auto自动声明变量(一般省略)
extern声明外源变量
register声明寄存器变量
static声明静态变量
typedef用来给复杂变量或函数取名

🌀12.1.4 其它类型关键字(3个)

关键字符号作用
const声明只读变量
sizeof计算存储空间大小
volatile说明变量在程序执行中可被隐含的改变

🌠12.2 关键字选讲

这里我们选讲几个关键字,后面如果遇到再给大家补充。

🌀12.2.1 auto

auto是自动申明变量的关键字,C语言中数据类型前面基本都有它

int main()
{
	auto int a = 10;
	//由于局部变量声明都需要加auto,所以一般省略

	return 0;
}

🌀12.2.2 extern

extern关键字的作用:
1:声明外部变量 2.声名外部函数

test_1.c下文件

int g_val = 2022;

test_2.c下文件

//声明外部符号
extern int g_val;

int main()
{
	printf("%d\n", g_val);
	return 0;
}

这时,就打印出了2022.
在这里插入图片描述

我们还可以声明外部函数。

test_3.c下文件

int Add(int x, int y)
{
	return x + y;
}

test_4.c下文件

//声名外部函数
extern int Add(int, int);//这里只需要写函数体内变量类型即可

int main()
{
	int a = 3;
	int b = 5;
	
	int c = Add(a, b);

	printf("%d\n", c);

	return 0;
}

这时便打印出了数字8.
在这里插入图片描述

🌀12.2.3 typedef

typedef常用来声明复杂的类型,或者使变量名具有实际意义,提高代码可读性。

typedef unsigned int uint;


int main()
{
	unsigned int num;
	uint num2;

	return 0;
}

这里unit就和unsigned int具有了同样的意义。

🌀12.2.4 register

计算机内部存储单元有哪些呢?
1.寄存器
2.高速缓存
3.内存
4.硬盘

由此我们得知寄存器关键字register自然就是将数据存放在寄存器里。

存储金字塔
在这里插入图片描述

由金字塔我们得知寄存器即为访问速度最快的存储单元,同时也是造价最为昂贵的单元,所以我们不能想当然的将数据放入寄存器,需要有选择的放入。同时我们也需要注意寄存器空间有限,不能大量放入数据

需要将数据放入寄存器的情况
1.局部变量(访问速度快,方便使用)
2.不会被写入的数据(本身register就是方便快速读取,如果写入内存,反而是错误的)
3.需要高频读取的变量

register 使用说明

int main()
{
	register int a = 10;

	return 0;
}

注意这里的register只是建议将该数据放入寄存器,具体放不放入最终还是由计算机来决定,不过现在大部分编译器会将自己认为合适的变量放入寄存器,不需要人为操作。
注意
既然我们都将变量放入寄存器的,还能不能取内存中的地址啊——显然是不能

int main()
{
	register int a = 10;

	int* p = &a;

	printf("%p", p);

	return 0;
}

在这里插入图片描述

🌀12.2.5 static

static关键字:
1.修饰局部变量
2.修饰全局变量
3.修饰函数

本质都是将其改为静态变量,我们先来了解一下计算机的分区
在这里插入图片描述
接下来我们再来一一分析。
修饰局部变量

void test()
{
	int a = 3;
	a++;

	printf("%d ", a);
}
int main()
{
	int i = 0;
	while (i < 10)
	{
		test();
		i++;
	}

	return 0;
}

在这里插入图片描述
这个程序打印出10个4相信大家应该是没问题的。那么如果我们在函数体变量名前加static呢?
在这里插入图片描述
太神奇了,竟然打印出了4-13,为什么呢?

普通的局部变量是放在内存的栈区的,进入局部范围变量创建,出了局部范围变量就销毁。但当static修饰变量时,局部变量是在静态区开辟空间的,这是它出了局部范围就不会被销毁,下一次进入作用域时,使用的是上次遗留的数据。(改变了存储位置,栈区->静态区,使得其生命周期发生变化)

修饰全局变量

test_1.c下文件

static int g_val = 2022;

test_2.c下文件

//声明外部符号
extern int g_val;

int main()
{
	printf("%d\n", g_val);
	return 0;
}

这里打印的还是不是2022呢?

在这里插入图片描述
编译器这里报错了。那是为什么呢?extern不是可以声明外部变量吗?

全局变量是有外部链接属性的,如果全局变量被static修饰,外部链接属性就变成了内部链接属性,其它源文件就没法通过这个链接属性找到这个变量,故static修饰的全局变量只能在自己的.c文件内部使用

修饰函数

函数也是具有外部链接属性的,故用static修饰展现出来的效果跟全局变量一样,这里不再赘述。

注意
1.外部链接属性——全局变量与函数
2.内部链接属性——static
3.无链接属性——局部变量

⚡13.#define定义和宏

我们常常需要在程序中定义某个重要的数据,方便后续使用。

🌠13.1 定义标识符常量

//#define 定义标识符常量
#define MAX 1000
#define STR "abcdef"

int main()
{
	printf("%d\n", MAX);
	int a = MAX;
	int arr[MAX] = { 0 };

	printf("%d\n", a);
	printf("%s\n", STR);

	return 0;
}

在这里插入图片描述

#define定义的标识符常量可以在任何需要的地方使用,包括打印,定义数组,增加代码可读性等。

🌠13.2 定义宏

我们写程序时常常用函数来封装程序,通过#define也能实现部分函数功能。

//函数
int Add(int x, int y)
{
	return x + y;
}

//宏
//#define 是一个预处理指令 
#define ADD(x,y) ((x)+(y))
#define MAX(x,y) ((x)>(y)?(x):(y))

int main()
{
	int a = 10;
	int b = 20;
	int c = ADD(a, b);
	int d = Add(a, b);
	int e = MAX(a, b);

	printf("c = %d, d = %d, e = %d\n", c, d, e);

	return 0;
}

在这里插入图片描述
这里定义宏和定义函数实现了同样的功能。值得注意的是宏是参数替换的,函数是传参

⚡14. 指针

🌠14.1 内存与地址

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址
在这里插入图片描述

那么地址如何查找呢?就像我们生活中的数据,大学生学籍信息也需要存储并查找,在C语言中我们给查找地址的工具取了个名字——指针

🌠14.2 指针的使用

🌀14.2.1 &-取地址操作符

在C语言中我们用&操作符来取地址。

int main()
{
	int a = 10;

	printf("%p\n", &a);

	return 0;
}

在这里插入图片描述

也可以通过监视来查看它的地址。
在这里插入图片描述

int类型占四个字节,y因此在内存单元中有四个地址,而我们打印只打印出第一个字节单元的地址

🌀14.2.2 定义指针变量

我们通过定义指针变量来存储变量的地址,用 *p来代表指针变量,其中 * 是解引用操作符。注意*运算符是双目操作符,而解引用操作符是单目操作符

int main()
{
	int a = 10;//4个字节
	int* pa = &a;//pa是创建出来存放地址(指针)的,pa就是指针变量
	
	printf("%d\n", *pa);

	char b = 'w';
	char* pb = &b;//字符型就用字符型指针存放

	*pa = 20;//*是解引用操作符,*pa就是通过pa中存放的地址,找到pa所指的空间
	//与a=20等价

	printf("%d\n", *pa);
	printf("%d\n", a);
	printf("%c\n", b);
	printf("%c\n", *pb);
	return 0;
}

在这里插入图片描述

*pa,*pb在这里直接就是a,b的意思,相当于直接指向把pa,pb所存地址也就是a,b,通俗易懂一点也就是 *pa,*pb起到了拜访的作用

🌀14.2.3 指针变量的大小

我们前面用过sizeof来计算过数据类型关键字的大小,这里我们同样用来计算指针变量的大小。

int main()
{
	//sizeof计算的是无符号整数的
	//对应的打印格式规范写法是%zu

	printf("%zu\n", sizeof(char*));
	printf("%zu\n", sizeof(int*));
	printf("%zu\n", sizeof(long*));
	printf("%zu\n", sizeof(long long*));
	printf("%zu\n", sizeof(short*));
	printf("%zu\n", sizeof(float*));
	printf("%zu\n", sizeof(double*));

	return 0;
}

在这里插入图片描述

这是在32位系统下,在64位系统下,打印结果就变成了8个字节,这是为什么呢?

电脑本身有一层地址线(32/64),在32位系统下,地址线也就转化成了1/0的二进制组成的电信号,共有2的32次方个,每个1/0占一个bit位,每8个bit位构成一个字节,所以地址存放起来就是4个字节,同理64位下就需要8个字节。
在这里插入图片描述

⚡15. 结构体

C语言中的变量类型除了我们之前介绍的几种基本类型(如int,char)还有许多种类型,如学生的学籍信息这种复杂对象就同时包含了多种信息,这时就要用结构体来描述了。

🌠15.1结构体基本结构

struct Stu {//定义结构体
	char name[20];
	int age;
	float score;
};
int main()
{
	struct Stu s;//定义变量

	scanf("%s %d %f", s.name, &s.age, &s.score);//输入数据
	printf("%s %d %.f", s.name, s.age, s.score);//输出数据

	return 0;
}

在这里插入图片描述

此处我们用struct来定义结构体,struct后面那部分就是定义的结构体变量名,我们可以利用这个来任意定义变量,在变量后加入“.”操作符即可实现对结构体内容的访问。其次注意数组名本身就是地址,输入时不需要再取地址。

🌠15.2结构体指针结构

我们也可以通过指针实现对结构体的访问

struct Stu {
	char name[20];
	int age;
	float score;
};
void Print(struct Stu* ps)
{
	//1.
	printf("%s %d %f\n", (*ps).name, (*ps).age, (*ps).score);
	//2.'->'操作符左边为结构体指针,右边为结构体成员
	printf("%s %d %f\n", ps->name, ps->age, ps->score);
}
int main()
{
	//数组名本身就是地址,不需要再取地址
	struct	Stu s1 = { "zhangsan",20,95.5f };
	struct  Stu s2 = { "lisi",40,99.8f };
	// '.'操作符,左边结构体变量,右边结构体成员

	printf("%s %d %f\n", s1.name,s1.age,s1.score);

	Print(&s2);

	return 0;
}

在这里插入图片描述

这里的Print函数中的函数名传入的参数是结构体指针变量,由此我们通过传入s2的地址也就是&s2实现了传参,定义结构体指针变量和定义基本指针变量差不多,此外*ps和我们上节讲的一样和s表达同样的意思.同时我们通过指针也就衍生出了另一种访问方法结构体指针->结构体成员


⚡16. 结语

到这我们的C语言就肝完啦,相信读完这两篇文章的朋友们已经了解了C语言的基本知识,下一篇博客我们将会正式详细的讲C语言了,学习永无止境。希望我的博客对大家有所帮助,如果喜欢的可点赞+收藏哦,也随时欢迎大家在评论区及时指出我的错误。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guaabd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值