C语言—指针(全面总结)

一: 致命打击 ❤️

(一)和指针相关的简单知识你了解多少?

指针数组了解吗?
函数指针了解吗?
指向指针的指针了解吗?💔
指向函数的指针数组还想了解吗?💔 💔

二:“💀灵魂💀”简介

(一)基础储备

①&运算符:查找地址。(❓不知道你是否想到了 scanf() 函数,scanf(“%d”,&x); scanf()函数就是从用户那里得到了数据之后存放到变量 x 的地址上的。)

②*运算符:间接运算符或称为解引用运算符,就是“解封"的意思(敏感词汇💥)

解除地址的封印,根据地址来找住在这里的对象)

③“解除地址的封印”:从字面上理解,就是解除地址的封印啊,就是挖开这个地址,看看这个地址上有什么东西(💪简单粗暴的,往往是最好的解决方式👏)。

很好👀。那么假如有 int a; &a 就代表变量a的地址,
那么 *(&a) 代表的还是变量 a 喽。我说的有道理吧(解除地址的封印)

(二)什么是指针?

从根本上来看,指针就是一个值为内存地址变量
🌀*分析:
①值为地址:说明指针是存储了一个值,这个值是某个地址,地址不就相当于我们家的门牌号吗🐶

②变量:指针也是一个变量类型,就像整形变量、字符型变量一样,说明指针变量也占据空间,那么也就是说中指针也有自己的地址,
那么也就是说可以用另一个指针来指向一个指针喽🌚,因为指针也是有地址的啊,那就是存在"指向指针的指针喽"

我说的是不是很有道理?💕💕💕💕

(三)为什么说指针是C语言的灵魂

在我看来,所有的编程语言几乎都是一样的,都是为了让计算机来来实现某个功能,只不过是简单与复杂罢了,可能是因为编程初学者的头发都比较旺盛,所以C语言有了指针,让C语言变得特别灵活(数组指针、指针数组、指向函数的指针等等),大大大大的提高了编程的效率,也大大大大大的提高了我们学习的难度。如果没有指针,可能在工作中没有人会愿意选择C语言来实现编程,毕竟编程语言是越来越简洁的,比如后续的Java、Pathon等等。

不管指针有多难,不管你现在指针有多么的反感,我都希望宝子们能够沉下心来💕💕,慢慢学习指针,我也是学了很久的指针才稍微搞懂了其中的奥秘。加油~💕💕!

(四)指针的声明

整型变量的声明是: int x;
那指针变量的声明能否写成 pointer p; 呢?🐳
显然是不可以的🌝,因为在声明指针变量的同时,必须要让指针指导它指向的变量的类型,这样它才能知道自己指向的空间的类型(因为不同的类型所占用的内存空间是不同的),那么指针该如何定义呢👻👻👻?

①首先要有一个标识来说明声明的变量是一个指针的类型

②要标明所声明的指针指向的数据的类型

eg:

int * pi; //pi是一个指向int类型变量的指针✈️

char * pc; //pc是一个指向char 类型变量的指针✈️

float * pf; //pf是一个指向float类型变量的指针✈️

pi、pc、pf是指向不同类型变量的指针,也就是说pi、pc、pf上储存的都是对应变量类型的一个地址,那么*pi 就代表一个 int 类型变量;

*pc 就代表是一个 char 类型的变量;

同理 *pf 也就是代表一个指向float类型的变量

(现在是不是稍微有了点儿头绪呢?🚀 🚀🚀 🚀)

(五)指针变量和整数类型

地址,好像都是整数数据,没有0.5的内存存在,既然是这样,那么也就是说指针存储的数据类型都是整数类型呗,那么指针变量不就是整数类型吗💯?

想啥呢,臭宝儿💩,指针实际上是一个崭新的类型,其实我也不知道为什么👻👻,
明明它存储的就是整数啊,
希望读者能帮助我解答这个问题,哈哈哈🎉🎉。

一些处理整数的操作不能用来处理指针的,比如可以把两个整数相乘,但是不能把两个指针来相乘,

不服气的话你可以去试试,

明说,指针可以相加,可以相减,可以指针++,指针- -

(六)提前感受一波指针的魅力吧

😃😃😃😃😃😃😃

#include<stdio.h>
void change1(int x,int y)    //传入普通的int类型数据
{
	int t;
	t=x;
	x=y;
	y=t;
	return;
}
void change2(int *x,int *y)   //传入指向int类型的指针,即传入的是地址
{
	int t;      //交换地址上的值
	t=*x;        //传入的是地址,而需要交换的是地址上的值,所以要用 *x 、*y ,来获取 x、y 的值来进行交换
	*x=*y;
	*y=t;
	return;
}
int main()
{
	int x,y;
	x=1;
	y=3;
	printf("x=%d\ny=%d",x,y);    //初始数据
	change1(&x,&y);              //调用函数change1
	printf("\nchange1:");
	printf("\nx=%d\ny=%d",x,y);     //x,y的值没有交换
	printf("\n*****************************************");
	change2(&x,&y);         //调用函数change2
	printf("\nchange2:");
	printf("\nx=%d\ny=%d",x,y);    //x,y的值进行了交换
	return 0;
}

运行结果
从上面这个简单的例子中你应该有了一点自己的见解,是不是说想要交换变量的值,准确来说是改变另一个函数中数据的值,就要用到指针来传递变量的地址来实现呢?
当需要在函数中访问另一个函数中的数据时,可以把指针作为函数的参数。

(七)重新认识变量(名称、值、地址)

🔔编写程序时可以认为变量具有两个属性:名称和值(当然还有其他性质,如类型,现在暂不讨论)。计算机编译和加载程序后认为变量也有两个属性:地址和值。地址就是变量在计算机内部的名称。
💨💨在许多语言中,地址都归计算机负责管理,对编程者隐藏,然而在C语言中,编程者可以通过地址运算符&来获取变量的地址,通过解引用运算符来获取地址上的值。
🔥🔥简而言之,普通变量把值作为基本量,把地址作为通过&运算符获取的派生量,而指针变量把地址作为基本量,把值作为通过*运算符获取的派生量。
💨💨虽然打印地址可以满足我们的好奇心,到那时这并不是&运算符的主要用途,更重要的是使用
和&运算符来操纵地址和地址上的内容。

三:指针和数组

(宝子,要认真听o)💕💕💕💕💕

(一)指针和数组的关系

一句话,数组表示法其实是在变相的使用指针。

(二)指针的相关操作

😑😑回顾😑😑:数组名是该数组首元素的地址。也就是说,如果flizany是一个数组,那么下面的关系成立:

int flizany[10];
flizany=&flizany[0];

两者都表示数组flizany数组首元素的地址,两者都是常量,在程序运行的过程中不会改变,但是可以通过把两者赋值给指针,通过指针的运算来间接对他们两者进行运算。

1.把数组赋值给指针(地址)

int *p1;
p1=flizany;

int *p2;
p2=&flizany[2];

2.解引用指针

*p1就是flizany[0上的值,两者等价;
同理,*p2就是flizany[2]上的值,两者等价;

3.解引用未初始化的指针

❗️ ❗️ ❗️❗️ ❗️ ❗️❗️ ❗️ ❗️

宝子~你一定要牢记:千万不要解引用未初始化的指针。
why❓
考虑下面的例子:

int * pt;
*pt=5;

很好👍👍👍,现在我想问问宝子们💕:指针 pt 指向哪里呢?谁的值又是 5 呢?是昨天定义的变量 x 吗?还是上学期定义的变量 y 啊?👊👊

第2行的意思是把5储存在pt指向的位置,但是pt未被初始化,其值是一个随机值,所以并不知道 5 将会被储存在何处,这可能不会出什么错,也可能会擦写数据或者代码,或者导致程序崩溃。

🔥🔥🔥切记:创建一个指针时,系统只分配了储存指针本身的内存,并没有分配储存数据的内存。因此,在使用指针之前,必须先用已分配的地址来初始化它。

🚀🚀例如:可以使用一个现有变量的地址来初始化该指针(使用带指针形参的函数时就属于这种情况)。或者还可以用malloc()函数来动态申请空间。

总之,无论如何,在使用指针时千万不要解引用未初始化的指针。

记住了吗,宝儿子💕💕?

4.指针与整数相加(减)

p1+1;---->代表指针指向数组flizany的下一个元素,即flizany[1]🚀

p2-1 ;---->代表指针指向数组flizany的上一个元素,即flizany[1]🚀

5.递增(递减)指针

我有点儿乏了,这一小部分我不想写了,就是这么随意🙉,自己类比“指针与整数相加(减)”吧
温馨提示:前缀或者后缀递增递减都是可以用的O💌💌

6.指针求差

p2-p1;---->代表两个指针中间相差的元素个数,并不是字节数哦。

🚀🚀回想一下指针声明的时候为什么要让你指明指针指向的数据类型,指明了数据类型,才能知道需要对少字节哦,是否顿悟了🙀🙀🙀

7.指针比较

🚀🚀(洗脑时间)指针的值是地址,地址的值有大小,所以指针当然可以进行比较,不就是指针大的在后,指针小的在前吗,简简单单,真的是这样吗?

☀️别看了,我是不会告诉你的💢,就问你敢不敢自己动手去写代码试试🙉🙉🙉(可以作为条件语句或者循环语句的判断条件来测试O)

(三)指针和数组的关系图

在这里插入图片描述

从本质上看,同一个对象有两种表示方法

实际上,C语言标准在描述数组表示法时确实借助了指针。

也就是说,定义 ar[n] 的意思是 *(ar+n)。可以认为 *(ar+n)的意思是“到内存ar的位置,然后移动n个单元,检索储存在那里的值”。**

注意💕💕 *(ar+n) 和 *ar+n 代表的意思不同,间接运算符(*)的优先级高于(+),所以*ar+n,相当于(*ar)+n

四:指针和多维数组

(💕💕宝儿,这也是重点,作为新手咱们精通二维数组就足够了)

(一)指针和多维数组之间的关系

👑👑👑为了方便理解,在此我用一个例子来讲解他们之间的关系

假设有下面的声明:

🚀🚀 int zippo[4][2]; //二维数组,内含 int 数组的数组

数组名 zippo 是该数组首元素的地址。

zippo 的首元素是一个内含两个int值的数组,所以zippo是这个内含两个int值的数组的地址。

  1. 🏰因为 zippo 是数组首元素的地址,所以 zippo 的值和 &zippo[0] 的值相同。而 zippo[0] 本身是一个内含两个整数的数组,所以zippo[0]的值和它首元素(一个整数)的地址(即 &zippo[0][0] 的值)相同。简而言之,zippo[0] 是一个占用一个int大小对象的地址,而zippo是一个占用两个int大小对象的地址。由于这个整数和内含两个整数的数组都开始于同一个地址,所以 zippo 和 zippo[0] 的值相同。🐒🐒💣💣💣

  2. 🏰给指针或者地址加1,其值会增加对应类型大小的数值。在这方面,zippo 和 zippo[0] 不同,因为 zippo 指向的对象占用了两个 int 大小,而 zippo[0] 指向的对象占用了一个int大小。因此,zippo+1 和zippo[0]+1 的值不同。🐒🐒💣💣💣

  3. 🏰解引用一个指针(在指针前使用*运算符)或在数组名后使用带下标的[]运算符,得到引用对象代表的值。因为 zippo[0] 是该数组首元素( zippo[0][0] )的地址,所以 *(zippo[0]) 表示储存在 zippo[0] [0] 上的值(即一个int类型的值)。与此类似,*zippo代表该数组首元素(zippo[0])的值,但是 zippo[0] 本身是一个 int 类型的地址。该值的地址是 &zippo[0][0] ,所以 *zippo 就是 &zippo[0][0] ,即一个int类型的值。简而言之,zippo 是地址的地址,必须解引用两次才能获得原始的值。地址的地址或指针的指针就是双重间接的例子。🐒🐒💣💣💣

💩💩看不懂了吧?懵b了吧? 看不懂就对了👊👊,有一说一,我也有点儿看不懂😐😐😐

(二)指针结合多维数组的运算

为了方便宝子们的理解,依旧使用上述定义的二维数组来进行说明:

💥💥与zippo[2][1] 等价的指针表示方法是 *(*(zippo+2)+1)

可能你看了这个比较懵逼,没关系,下面我将为你一步一步的介绍缘由,

请宝子们认真学习哦:💕💕💕💕

🚀zippo ------> 二维数组首元素的地址(每个元素都是内含两个 int 类型元素的一维数组)

🚀zippo+2 ------>二维数组的第3个元素(即一维数组)的地址

🚀*(zippo+2)------>二维数组的第3个元素(即一维数组)的首元素(一个 int 类型的值)地址

🚀*(zippo+2)+1------>二维数组的第3个元素(即一维数组)的第2个元素(也是一个 int 类型的值)地址

🚀*( *(zippo+2)+1)------>二维数组的第3个一维数组元素的第2个 int 类型元素的值,即数组的第3行第2列的值(zippo[2][1])

看了上面的步骤,不知道是否有了新的认识呢,

如果还是没有头脑,不要着急,慢慢来✊✊,

多看几遍慢慢理解,需要时间的沉淀💌💌💌

(三)直接给宝儿上图

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

五:指针数组

(一)基本概念

你应该知道什么叫做整型数组、字符型数组吧?

数组元素为整型量,称之为整型数组;数组元素为字符型量,称之为字符型数组。

因此,若数组元素是指针,那是不是应该把它叫做指针数组呢?

是的,完全正确🚀🚀,终于猜对一次

🚁🚁指针也是有类型的,如果指针数组中的元素为整型指针,那么我们就把它称作整型指针数组。
🚁🚁同理,有float型指针数组、double型指针数组、char型指针数组等。

(二)定义规则

<类型名> *<指针数组名>[<元素个数>];
🐾🐾来给宝子们举个例子吧💕💕
如 int *p[10] ; 表示定义了一个整型指针数组p[10],它有10个元素p[0] , p[1] , p[2] , p[3] , … ,p[9] ,每个元素均为整型指针指针类型为 int*

(三)操作方法

在这里插入图片描述
简单理解就是一下儿声明了一大堆指针👍👍🚀🚀🚀🚀🚀🚀

六:数组指针

(一)定义

🚀🚀直接上例子:💕💕

int (*p)[2]; //这就是一个数组指针,指向一个内含两个int类型值的数组

(二)使用

在这里插入图片描述

七:指针和函数

(一)函数指针

1.基本概念

一个函数被编译连接后生成一段二进制代码,改代码的首地址称为函数的入口地址。

可以定义一种特殊的指针变量,专门用于存放函数的入口地址,

这种变量称为函数指针变量,简称函数指针。

(知道大概的意思就行了,关键是会使用)

2.定义

**语法格式:

<数据类型> (*<函数指针变量名>)(<参数类型表>);**

例如:

int (*fp)(int ,int);//定义一个函数指针变量fp,它指向具有两个整型参数且返回值为整型量的函数🚀🚀
int max(int ,int);
fp=max;

注意:

  1. 🚀🚀函数指针指向程序代码区,一般变量的指针指向数据区

  2. 🚀🚀(*fp)的小括号不能省,因为() 运算符的优先级高于 * 运算符,若省略,则变成int *fp(int ,int); 它表示返回指针值的函数。

  3. 🚀🚀函数指针不能进行++、–、+、-等运算,因为在程序的一次执行过程中,函数代码区的起始地址不会变动,即函数指针是指针常量。

3.使用

❗️❗️❗️引入函数指针的目的是为了编写通用函数
💕💕直接给宝子们来个我们财大OJ题吧,直说,我就是懒😇😇,

不想再敲一遍代码了,OJ可以直接复制代码,啊哈哈哈哈✌️✌️✌️✌️

  • 🚀🚀题目描述
  • 输入n和n个整数,然后按要求排序,若输入1,请输出升序排序序列;若输入2,请输出降序排序

序列,若输入3,请输出按绝对值升序排序序列。*

#include<stdio.h>
#include<math.h>
void sort(int a[],int n,int (*cmp)(int x,int y))
{
	int i,j;
	for(i=0;i<n-1;i++)
	{
		for(j=0;j<n-i-1;j++)
		{
			if((*cmp)(a[j],a[j+1]))
			{
				int t;
				t=a[j];
				a[j]=a[j+1];
				a[j+1]=t; 
			}
		}
	}
	for(i=0;i<n;i++)
	{
		printf("%d ",a[i]);
	}
	return ;
}
int CmpAsc(int x, int y)
{
 //如果x>y返回1,否则返回0;
 if(x>y)
 {
 	return 1;
 }
 else
 {
 	return 0;
 }
}

int CmpDec(int x, int y)
{
 //如果x<y返回1,否则返回0;
 if(x<y)
 {
 	return 1;
 }
 else
 {
 	return 0;
 }
 }
 
int CmpAbsAsc(int x, int y)
{

//如果abs(x)>abs(y)返回1,否则返回0
if(abs(x)>abs(y))
 {
 	return 1;
 }
 else
 {
 	return 0;
 }
}
int main()
{
	int a[100],i,n; 
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
    int slt;
 /*读入n和n个整数,存入数组a*/
  
   /*读入用户的选择,存入slt; */
	scanf("%d",&slt);
    switch(slt)
   {
     case 1:   sort(a, n, CmpAsc); break;
     case 2:   sort(a, n, CmpDec); break;
     case 3:   sort(a, n, CmpAbsAsc);break;
   }
	return 0;
}


慢慢看吧 💩💩,加油✊✊💕💕

不懂得可以私信我,或者评论区留言哦,

全心全意为人民服务💕💕

(二)指针函数

1.基本概念

你应该知道函数的返回值可以是基本类型量,如整型、实型、字符型等,

那么函数的返回值当然也可以是指针类型的量啊。

那么返回指针的函数我们就可以称之为 指针函数 🚀🚀🚀🚀。

2.定义

语法格式:
<数据类型> * <函数名>(<参数列表>);

例如:

int *func(...)
	 {
	 	...
	  } 

3.使用

继续上财大OJ例题:(懒是会上瘾的😇😇)

  • 🚀🚀题目描述
  • 读入一个实数,输出该实数的小数部分,小数部分若多余的末尾0,请去掉。如输入
    111111.12345678912345678900
    则输出0.123456789123456789。若去掉末尾0之后小数部分为0,则输出“No decimal part”。注意该实数的位数不超过100位。
    请定义并使用如下函数。
    char *decimal(char p)
    {
    将字符串p表示的实数的自小数点开始的小数部分存入一个字符串,并由函数返回,若p为“123.456”,则返回的字符串为“.456”。若小数部分为0,返回空指针NULL。
    }
    输入
    输入一个实数。不超过100位。
    输出
    输出小数部分,输出占一行。
#include<stdio.h> 
#include<string.h>
char*decimal(char *p)
{
	int i,j=0;
	for(i=(strlen(p)-1);i>=0;i--)
	{
		if(*(p+i)=='0'&&*(p+i-1)!='0')
		{
			*(p+i)='\0';
		}
		else if(*(p+i)!='0')
		{
			break;
		}
	}
	while(*(p+j)!='.')
	{
		j++;
	}
	if(i==j)
	{
		return NULL;
	}
	else
	{
		return (p+j);
	}
	
}
int main()
{
	char num[100],*p;
	int i;
	scanf("%s",num);
	p=decimal(num);
	if(p)
	{
		printf("0%s",p);
	}
	else
	{
		printf("No decimal part");
	}
	return 0;
}

慢慢看吧啊 💩💩,加油✊✊💕💕

不懂得可以私信我,或者评论区留言哦,

全心全意为人民服务💕💕

(我摊牌了,这句话我是复制的上面的,都说了 懒是会上瘾的 🐒🐒🐒)

八:指向指针的指针

(一)概念

🚀🚀指针变量用于存放地址值,它本身也占用若干存储单元,也是有起始地址的。

那么我们同样可以定义一个变量来储存它的地址。

存放指针变量起始地址的变量,称为指向指针的指针

✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️✈️

(二)定义

<类型说明符> ** <指针变量名>;(注意是两个)*

例如:

int x=3,*p1,**p2;
     p1=&x;
     p2=&p1;
	  

在这里插入图片描述
这里又点绕,认真阅读💕💕💕💕

(三)使用

定义一个指向指针的指针,用它指向指针数组。

#include<stdio.h>
int main()
{
	char **p;
	char *s[]={"up","down","left","right"};
	int i;
	p=s;
	for(i=0;i<4;i++)
	{
		printf("%s\n",*p++);
	}
	return 0;
} 

在这里插入图片描述
有时候我就在想,知道个指针不就好了吗,为啥还会有指向指针的指针,

到底该在什么情况下才适合用到指针的指针。

但是,回头再想想,知道了总比不知道要好,“指向指针的指针”听起来就很NB。

九:财大OJ例题找Bug

(本道题涉及指针指向结构体的相关知识)

这道题是我在写完本片博客后过了几天加进来的,觉得这道题很有价值,代码是我自己写的,里面只有一个bug,调试了将近两个小时,从坐着找bug,到躺着找bug,再到走着想着bug,最后终于找到了问题所在,
下面我把OJ原题附上,并且附上我的错误代码(只有一处错误),既然我又回过头特意把这道题放在本篇博客,相信读者也能隐约感受到这段代码中的bug和指针有关(算作是个小小提示吧),

希望读者能够耐心读完这段代码,有疑问欢迎进行提问,我将尽我最大的能力帮助读者解答。

题目描述
从键盘输入若干个学生的信息,每个学生信息包括学号、姓名、3门课的成绩,计算每个学生的总分,输出总分最高的学生的信息。

输入
首先输入一个整数n(1<=n<=100),表示学生人数,然后输入n行,每行包含一个学生的信息:学号(12位)、姓名(不含空格且不超过20位),以及三个整数,表示语文、数学、英语三门课成绩,数据之间用空格隔开。

输出
输出总成绩最高的学生的学号、姓名、及三门课成绩,用空格隔开。若有多个最高分,只输出第一个。

样例输入 Copy
3
541207010188 Zhangling 89 78 95
541207010189 Wangli 85 87 99
541207010190 Fangfang 85 68 76

样例输出 Copy
541207010189 Wangli 85 87 99

#include<stdio.h>
//定义结构体 
typedef struct Student 
{
	char num[13];
	char name[21];
	int score[3];
} lucky;
//给结构体赋值 
lucky *Student_puts(lucky *pc)
{
	scanf("%s",&pc->num );
	scanf("%s",&pc->name );
	int i=2;
	while(i>=0)
	{
		scanf("%d",&pc->score[i]);
		i--;
	 } 
	 return pc;
}
//打印结构体中的数据
void show(lucky *pc)
{
	printf("%s ",pc->num);
	printf("%s ",pc->name);
	int i=2;
	while(i>=0)
	{
		printf("%d ",pc->score[i]);
		i--;
	}
	return ;
 } 
 
 //计算对应学生的总分数
 int number(lucky *pc) 
 {
 	int numbers=0;
 	int i=2;
	while(i>=0)
	{
		numbers+=pc->score[i];
		i--;
	}
	return numbers;
 }
 
int main()
{
	int n;
	lucky *pc_1,*pc_2;
	lucky student_max,student_new;
	scanf("%d",&n);
	pc_1=Student_puts(&student_max);
	while((n-1)>0)
	{
		pc_2=Student_puts(&student_new);
		if((number(pc_1)) < (number(pc_2)))   //不加等于号,因为题目要求是成绩重复的情况下只打印第一个学生的信息
		{
			pc_1=pc_2;
		}
		n--;
	}
	show(pc_1);
	return 0;
 } 

十:完结

讲真的,我现在还没有完全理解指针相关的知识,已经学了很久了,中间也有停下来不断温习,反复看书,一遍又一遍,现在觉得我还有很多相关的知识没有搞懂,后续还是要多加努力的,我个人觉得学会指针还是很有必要的,学不会指针就相当于没有学C语言(仅代表个人观点)。

🚀🚀🚀以上就是我最近对指针相关知识点的大概总结,希望对大家能有帮助!!💕💕

🚀🚀🚀内容不全面,而且可能存在错误的地方,希望大家能够私信我进行纠正,不尽感激。💕💕

🚀🚀🚀我是一名编程初学者,这是我的第三篇博客,希望能够得到大家的支持,一起努力吧,加油🌻🌻🌻🌻🌻!!

拜拜🐾🐾🐾🐾🐾🐾
💕💕
💕💕
💕💕
💕💕

2022.05.09 || 1:56

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Duang~Lucky.Mr.Li

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

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

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

打赏作者

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

抵扣说明:

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

余额充值