chapter 9用户自己建立数据类型

9.1定义和使用结构体变量

9.1.1用户建立结构体类型

首先说一下什么是结构体类型,就是把咱们之前学过的,系统提供的变量,来一个复合打包。
比如

int a;
char b;
float c;
double d;
long long e;

现在我打包起来

struct student
{
	int a;
	char b;
	float c;
	double d;
	long long e;
}

为什么这样做呢,我们一般解决实际问题是,很多不同类型数据都存在相关练习。比如我描述一个人,可以从年龄,性别,学历,工作,四个角度去描述一个人,这四个不同变量类型。往往存在一定的联系。那我们把这些数据打包,组成一个组合数据,这样我们就能够用一个数据表示所有的情况,是不是很方便,精炼。
用户自己建立有不同类型数据组成的组合型数据结构,称之为结构体

一般形式:
struct 结构体名
{成员表列};

结构体名也叫“结构体标记”。成员列表也成为“域表“;
域表元素的命名规则: 类型名 成员名;

可以同时建立多个结构体,并且一个结构体可以是另外一个结构体的成员。

struct Date
{
	int month;
	int day;
	int year;
};
struct student 
{
	int num;
	char name[20];
	char sex;
	int age;
	struct Date birthday;
	char addr[30];
}

结构图

9.1.2 定义结构体类型变量

这里我们学习如何在程序中使用结构体变量;总的包括,定义结构体变量,然后初始化,最后能存取数值。这里我先讲解如何定义;
1.先声明结构体类型,再定义该类型的变量

 struct Date
{
	int month;
	int day;
	int year;
};
struct student 
{
	int num;
	char name[20];
	char sex;
	int age;
	struct Date birthday;
	char addr[30];
}//先声明结构体类型

struct student student1,student 2;//然后定义该类型的变量。

定义了两个变量,定义的类型式没有储存空间的,只有定义变量才有储存空间。
现在变量student 1,student 2;的结构如下图。
在这里插入图片描述2.在声明类型的同时定义变量

  struct Date
{
	int month;
	int day;
	int year;
};
struct student 
{
	int num;
	char name[20];
	char sex;
	int age;
	struct Date birthday;
	char addr[30];
} student 1,student 2;

一般形式:
struct 结构体名
{
成员列表
}变量名列表;

3.不指定类型名而直接定义结构体类型变量

一般形式:
struct
{
成员列表
}变量名列表;

这种方法的局限性在于,他只能定义变量名列表的变量,由于没有变量名,所以不能定义其他变量为此结构体了。

注意:
a.结构体类型和结构体变量完全是两个不同的概念;
b.结构体中的成员名比如num,和程序中的num完全是不同的概念。名字相同,但是表达的意义是不相同的。
c.结构体中的成是可以当作普通变量去使用的,可以运算,赋值等等,怎么引用,一般是结构变量名.成员名

9.1.3结构体变量的初始化和引用

看个例子;

/*把一个学生的信息(学号,姓名,性别,住址)放在一个结构体中,然后输出这个学生的信息*/ 
#include <stdio.h>
int main()
{
   struct student
   {
   	long int num;
   	char name [20];
   	char sex;
   	char addr[20];
   }a={10100,"wu mingda",'M',"XIN DE BAN DAO"};
   printf("NO.:%1d\nname:%s\nsex:%c\naddr:%s\n",a.num,a.name,a.sex,a.addr);
}

在这里插入图片描述
从上面的例子咱们可以看出,如何初始化一个结构体变量。

a={10100,"wu mingda",'M',"XIN DE BAN DAO"};
 如果想对某一起其中的元素单独初始化也可以(C99以上),如下:
 ={.num=1};//{a.name=1};也行
/*把一个学生的信息(学号,姓名,性别,住址)放在一个结构体中,然后输出这个学生的信息*/ 
#include <stdio.h>
int main()
{
	struct student
	{
		long int num;
		char name [20];
		char sex;
		char addr[20];
	}a={.num=1};//{a.name=1};也行
	
	printf("NO.:%1d\nname:%s\nsex:%c\naddr:%s\n",a.num,a.name,a.sex,a.addr);
}
其他元素没有被初始化的元素首先就是,数值型=0;字符型=\0;指针型:NULL;

如何引用结构体变量名字
结构体变量名.成员名
. 是成员运算符,优先级最高。

赋值:a.num=10010;同类型结构体变量的可以相互赋值;
可以进行各种运算;
可以引用结构体变量的地址:&student1;
也可以引用结构体变量成员名的地址:&student1.num;
如果成员本身就是一个结构体,如何引用呢;
student1.num;
student1.birthday.month;
注意结构体变量只能一个一个输出:
printf("NO.:%1d\nname:%s\nsex:%c\naddr:%s\n",a.num,a.name,a.sex,a.addr);
不能一次性输出,一次性读入:
printf("%s\n",student1);
scanf("%d,%s,%c,%s",%student1);

在看一个例题

 输入两个学生的相关信息,输出成绩较高的那个人相关信息
#include <stdio.h>
int main()
{
	struct student
	{
		int num;
		char name[20];
		float score;
	}student1,student2;
	scanf("%d%s%f",&student1.num,student1.name,&student1.score);
	scanf("%d%s%f",&student2.num,student2.name,&student2.score);
	printf("the higher score is:\n");
	if(student1.score>student2.score)
		printf("%d  %s  %6.2f\n",student1.num,student1.name,student1.score);
	else if(student1.score<student2.score)
		printf("%d  %s  %6.2f\n",student2.num,student2.name,student2.score);
	else 
	{
		printf("%d  %s  %6.2f\n",student1.num,student1.name,student1.score);
		printf("%d  %s  %6.2f\n",student2.num,student2.name,student2.score);
	}
	return 0;
} 

9.2使用结构体数组

9.2.1定义结构体数组

/*有三个候选人,每个选民只能投票一人,要求编一个统计票数的程序,先后输入被选人的名字
,最后输出各人的的票结果*/
#include <stdio.h>
#include <string.h>
struct person
{
  char name[20];
  int count;
}leader[3]={"Li",0,"zhang",0,"sun",0};

int main()
{
  int i,j;
  char leader_name[20];
  for(i=1;i<=10;i++)
  {
  	scanf("%s",leader_name);//把名字储存到数组中 
  	for(j=0;j<3;j++)
  		if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;
/* 
  		strcmp(字符串1,字符串2);
意思就是让两个字符串进行比较 ;如果两个比较等价;那么输出得结果就是0;
小于;那么输出的结果就是一个负整数;
大于;;;;;输出的结果就是一个正整数;
那么你坑定会问 ;怎么进行比较的呢;
首先自左向右进行比较;通过ascall

1)完全相同; 说明字符串完全相等;
2)有不同 以第一对为准;
3)如果两个字符串都是英语都是英文;大写小于小写;在英文字典在后面得位置为大;*/
  }
  printf("\nResult:\n");
  for(i=0;i<3;i++)
  	printf("%5s:%d\n",leader[i].name,leader[i].count);
  return 0;
  	
}

在这里插入图片描述
在这里插入图片描述
定义结构体数组的一般形式:

struct 结构体名
{
成员表列
} 数组名[数组长度];

或者

先声明定义一个结构体类型 ;
结构体类型 数组名[数组长度];

例如

struct person
{
   char name[20];
   int count;
}leader[3]={"Li",0,"zhang",0,"sun",0};初始化1
或者:
struct person
{
   char name[20];
   int count;
};
struct person leader[3]={"Li",0,"zhang",0,"sun",0};初始化2
初始化就是在定义的变量后面直接加上初始化表列;

9.2.2 结构体数组的应用举例

/*有n个学生的信息(包括学号,姓名,成绩),要求按照成绩的高低
顺序输出各个学生的信息*/
 #include <stdio.h>
 struct student
 {
 	int num;
 	char name[20];
 	float score;
  } ;//
  int main()
  {
  	struct student stu[5]={ {10101,"zhang",78 },{10103,"wang",98.5},{10106,"Li",86},{10108,"ling",73.5},{10110,"sun",100}};//
  	struct student temp;
  	const int n=5;
  	int i,j,k;
  	printf("the order is:\n");
  	for(i=0;i<n-1;i++)
  	{
  		k=i;
  		for(j=i+1;j<n;j++)
  			if(stu[j].score>stu[k].score) k=j;
  			temp=stu[k];stu[k]=stu[i];stu[i]=temp;
	  }
	  for(i=0;i<n;i++)
	  	printf("%6d %8s %6.2f\n",stu[i].num,stu[i].name,stu[i].score);
	  	printf("\n");
	  	return 0;
  }

在这里插入图片描述

9.3 结构体指针

每个结构体都有一个地址,定义一个指针变量,他只能储存结构体类型的地址的话,我称之为结构体指针。结构体指针可以指向结构体。

9.3.1指向结构体变量的指针

首先咱们看一个例子;

/*通过指向结构体变量的指针变量输出结构体变量中的相关信息*/
#include <stdio.h>
#include <string.h>
int main()
{
	struct student
	{
		long num;
		char name[20];
		char sex;
		float  score;
	};//定义一个结构体;
	struct student stu_1; //定义一个结构体变量
	struct student *p;//定义一个指针变量指向结构体
	p=&stu_1;
	stu_1.num=10101;
	strcpy(stu_1.name,"li lin");//字符串赋值函数;把"li lin"赋值stu.1.name;
	stu_1.sex='M';
	stu_1.score=89.5;
	printf("no.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",stu_1.num,stu_1.name,stu_1.sex,stu_1.score);
	printf("no.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",(*p).num,(*p).name,(*p).sex,(*p).score);//
	return 0;
	
} 
(*p).num;p是变量名字,包含地址,*p意思是指向结构体()优先级大于.num,
所以说先指向某一个结构体,然后就是找到里面对应的num;
 如果没有括号,就是.num优先于*运算符,所以显示p.num;p是变量名字;
 所以p.num没有意义;所以说必须加括号;

以下三种情况等价:
**
stu.num stu;本身相当于一个抽象的变量,所以就不代表地址的意思,直接就是数值
(*p).num;
p->num;->指向运算符。前面是地址,后面是具体那个元素;
**

9.3.2指向结构体数组的指针

#include <stdio.h>
struct student 
{
	int num;
	char name [20];
	char sex;
	int age;
};
struct student stu[3]={{10101,"lilin",'M',18},{10102,"ZHANG FANG",'M',19},{10104,"WANGMIN",'F',20}};
int main()
{
	struct student*p;
	printf("no.name                                 sex age\n");
	for(p=stu;p<stu+3;p++)
		printf("%5d %-20s %2c %4d\n",p->num,p->name,p->sex,p->age);
		return 0;
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/20191226215618270.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTg0MDA4Nw==,size_16,color_FFFFFF,t_70

9.4 用指针处理链表

9.4.1 什么是链表

在前面的学习中,当我们处理数据,比如ABCD苏格版每个班级的人数都不一样,我们处理数据的方法是建立一个数组,但是也存在一定的问题,我们建立一个数组的时候,只能建立最长的那个班级人数的数组,这样相对于其他班级人数少的时候,是不是对于数组来说就造成储存空间的一种浪费。那么我们能不能建立一种动态储存空间,能随班级的人数来动态分配内存,能够需要来动态建立储存单元的结构叫做链表。
在这里插入图片描述如图所示,链表必须要有一个
头指针 :只用来存放地址;
表尾:存放一个数据,而且其中存放指针地址的区域存放空指针,不知想任何类型。

看这个链表,去掉一头一尾部,剩下的中间那些称之为一个又一个的节点。
看这些节点,它包括两个东西:
a.用户需要用的实际数据
b.下一个节点的地址;

所以我们看一看链表有什么特点:
1.看上图,链表各节点之间的地址是可以不连续的。
2.结构体变量,用它去建立链表是最合适的。
3.在结构体中定义的某一个指针,根据定义的在指针类型,可以指向自己所在的结构体数据,也可以指向其他类型的结构体数据。
我们看一下:

struct student
{
	int num;
	float score;
	struct student *next;//定义的结构体上面两行就是所谓的实际数据,下面指针定义的就是只能只想自己的数据类型。
}

9.4.2建立简单的静态链表

我们看一个例子,建立一个静态链表:

/*建立一个简单链表,有三个同学的数据节点组成,要求输出节点的数据*/ 
#include <stdio.h>
struct student
{
   int num;
   float score;
   struct student *next;//地址指向下一个节点的关键。
} ;//建立一个结构体,可以用来充当各个节点了。
int main()
{
	struct student a,b,c,*head,*p;
   a.num=10101;a.score=89.5;
   b.num=10103;b.score=90;
   c.num=10107;c.score=85;
   head=&a;
   a.next=&b;
   b.next=&c;
   c.next=NULL;
   p=head;
   do
   {
   	printf("%ld%5.1f\n",p->num,p->score);//p是地址,->只想运算符,p->意思就是指向b这个结构体了,然后·取num的数值。
   	p=p->next;//p是地址,->只想运算符,p->意思就是指向b这个结构体了,然后取next值
    } while(p!=NULL);
   return 0;
 }

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

9.4.3 建立动态链表

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

/*写一个函数建立一个有三个学生数据的单向动态链表*/
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct student) //测量字节
struct student
{
 long num;
 float score;
 struct student*next;
};
int n;
struct student *creat(void)
{
 struct student*head;
 struct student*p1,*p2;
 n=0;
 p1=p2=(struct student*)malloc(LEN);//建立一个动态储存区返回一个地址,这个动态储存区的长度为LEN;
 scanf("%ld,%f",&p1->num,&p1->score);
 head=NULL;
 while(p1->num!=0)
 {
 	n=n+1;
 	if(n==1)head=p1;
 	else p2->next=p1; 
 	p2=p1;
 	p1=(struct student*)malloc(LEN);
 	scanf("%ld,%f",&p1->num,&p1->score);
  } 
  p2->next=NULL;
  return(head);
}

int main()
{
 struct student *pt;
 pt=creat();
 printf("\nnum:%ld\nscore:%5.1f\n",pt->num,pt->score);
 return 0;
}

里面出现了n.一开始n=0,然后n=1;n=2,3,4;
n=0;还没有建立链表;
n=1;建立了一个链表节段;赋值时把p1给head,让p2等于p1;
n=2;建立了第二个链表节段;赋值时让p1等于上一个变量中的next,p2等于此时的p1;
所以n可以作为建立链数的标志。

9.4.4输出链表

首先按一个例子,编出一个输出链表的函数。

#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct student)//用sizeof 测量结构体的长度字节,让LEN恒等于这个字节。
struct student
{
   long num;
   float score;
   struct student *next;
};//定义一个结构体。包含两个数据,和一个指针。
int n;
void print(struct student *head)//定义一个函数。形参定义为 struct student *head .输入一个结构体变量的地址。让他传递到这个函数。
{
   struct student *p;//定义一个为结构体变量
   printf("\nnow,these.%d records are :\n",n);//输出n
   p=head;
   if(head!=NULL)
   {
   	do
   	{
   		printf("%ld %d5.1f\n",p->num,p->score);
   		p=p->next;
   	}while(p!=NULL); 
   }
   
}
整体将这个链表输出。直到遇到NULL为止。

也就是说在print 函数里面

	do
   	{
   		printf("%ld %d5.1f\n",p->num,p->score);
   		p=p->next;
   	}while(p!=NULL); 

这就是输出链表的关键,用do while 循环。也可以用while 循环。这里不需要计数,只要遇到NULL就行。所以用 do-while 和 while循环是比较好的。

我们把上面的一道例题和这一道立体综合起来。

/*建立一个动态链表,然后输出*/
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct student)//
struct student
{
	long num;
	float score;
	struct student*next;
};
int n;

struct student *creat(void)//建立一个动态链表
{
	struct student*head;
	struct student*p1,*p2;
	n=0;
	p1=p2=(struct student*)malloc(LEN);//建立一个动态储存区返回一个地址,这个动态储存区的长度为LEN;
	scanf("%ld,%f",&p1->num,&p1->score);
	head=NULL;
	while(p1->num!=0)
	{
		n=n+1;
		if(n==1)head=p1;
		else p2->next=p1; 
		p2=p1;
		p1=(struct student*)malloc(LEN);
		scanf("%ld,%f",&p1->num,&p1->score);
	 } 
	 p2->next=NULL;
	 return(head);
}


void print(struct student*head)//建立一个输出链表的函数
{
	struct student *p;
	printf("\nnow,these.%d records are :\n",n);
	p=head;
	if(head!=NULL)
	{
		do
		{
			printf("%ld %5.1f\n",p->num,p->score);
			p=p->next;
		}while(p!=NULL); 
	}
	
}

int main()//主函数
{
	struct student *head;
	head=creat();
	print(head);
	return 0;	
}

在这里插入图片描述

9.5 共用体类型

9.5.1 什么是共用体类型

前面我们所学习了结构体类型,结构体类型是将所有不同类型的数据联合在一起。
在这里插入图片描述而我们现在学习的共用体类型,用同一段内存单元存放不同的类型的数据,是选择里面最长的一个数据,就拿这个最长的长度,作为共用体结构的长度。共用体是通过覆盖的实现的。
在这里插入图片描述共用体的一般形式:

union 共用体名
{
成员列表
} 变量列表;

具体有如下三种定义形式:

union data
{
	int i;
	char ch;
	float f;
}a,b,c;
///
union data
{
	int i;
	char ch;
	float f;
};
union data a,b,c;
/这种定义的比较多
union 
{
	int i;
	char ch;
	float f;
}a,b,c;
和结构体一样,这个定义完只能有一次定义变量的机会,因为它没有定义变量名。

9.5.2 引用共用体变量的方式

引用公用体变量看看下面

a;错误
a.i;正确
a.ch;正确
a.f;正确
printf ("%d",a);错误
printf("%d",a.i);正确

首先咱们看一下,共用体虽然是一个综合的结构体,但是呢,他是具体表示某一个变量的。你如整型 浮点型。所以你不能通过共用体名字去引用。他不具体表示哪一个变量。只有a.i等才可以,因为是具体表示某一个变量的。再看结构体,结构体名字就是本身表示一个变量。所以说结构体可以引用,但是共用体不可以引用。

9.5.3共用体类型的特点

共用体类型有以下特点:
1)共用体可以存放不同类型的数据,但是在某一瞬间只能存放其中一个成员。
在某一瞬间,共用体只能存放某一种类型的数据;
2)可以初始化,但是只能放一个数值;

union data
{
	int i;
	char ch;
	float f;
}a={1,'a',1.5};错误
union data a={16};正确
union data a={.ch='j'};正确,最好都加上.ch;之类的

3)共用体赋值时候直接按照那个数值的类型去储存,字节是类型中最大字节;
4)赋值后之前的数据会被覆盖,只有现在这个数据是有效的。
5)公用体变量的地址和他的成员的地址都是同一个地址。

&a.i=&a.c=&a.f;
&a的地址没有意义

6)变量名是不可以被赋值的,也不能被使用,需要具体到什么类型;
7)C99以后可以做函数参数(只提一下,以后学习中了解)

 有若干人员的数据,其中包括学生和老师。学生的数据中包括,姓名 号码 性别 职业 班级 。
 教师的数据包括:姓名,号码,性别 ,职业,职务,。要求制定一个表格来处理。
#include <stdio.h>
struct 
{
	int num;
	char name[10];
	char sex;
	char job;
	union
	{
		int clas;
		char position[10];
	}category;	
}person[2];

int main()
{
	int i;
	for(i=0;i<2;i++)
	{
		printf("please enter the data of person:\n");
		scanf("%d %s %c %c",&person[i].num,&person[i].name,&person[i].sex,&person[i].job);
		if(person[i].job=='s')
			scanf("%d",&person[i].category.clas);
		else if(person[i].job=='t')
			scanf("%d",&person[i].category.position);
		else 
		printf("\n");
		printf("No.name sex job class/position\n");
		for(i=0;i<2;i++)
		{
			if(person[i].job=='s')
				printf("%-6d%-10d%-4c%-10d\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.clas);
			else
			 	printf("%-6d%-10d%-4c%-10d\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.position);
		}	
	}
return 0;
} 

9.6 使用枚举类型

什么是枚举;就是自己去列举一些可能性,然后如果你定义一些变量;这些变量的取值,只能在这些可能性中取值。除非你改变枚举列表,否则你的变量不能取值在枚举之外的值。
怎么写一个枚举类型的结构,以及怎么去定义它
enum 枚举结构名
{
枚举表列(枚举常量)
}枚举变量;

如下:

enum weekday{sun,mon,tue,wed,thu,fri,sta};
enum weekday workday,weekend;
/
enum weekday{sun,mon,tue,wed,thu,fri,sta}workday,weekend;
/
enum {sun,mon,tue,wed,thu,fri,sta}workday,weekend;
也可以没有枚举结构名,但是相当于只能定义一次;

注意:
枚举元素是常量,他虽然也是由字符构成,看起来像变量,但是,他依旧是一个常量,所以他是不能够被直接赋值的。而且每个枚举元素都会被默认为一个整数;比如之前的sun就被默认0;mon就被默认1…以此类推。

printf("%d",sun);他是可以被输出的,输出的数值是0

而且每个枚举元素也可以被设置为特定的数值;然后后面没有被赋值的,就顺推加1;

 #include <stdio.h> 
enum weekday{sun=7,mon=5,tue,wed,thu,fri,sta};
int main()
{
	enum weekday a,b,c;
	a=tue;
	b=wed;
	c=sta;
	printf("%d  %d   %d",a,b,c);
	return 0;
 } 

在这里插入图片描述

/*口袋中有红,黄,蓝,百,黑5种颜色的球若干个,每次从口袋里
先后取出三个球,问得到三种颜色球可能的取法,输出每种排列的情况*/
#include <stdio.h>
int main()
{
   enum color{red,yellow,blue,white,black};
   enum color i,j,k,pri;
   int n,loop;//n 用来记录取法的可能。 
   n=0;
   for(i=red;i<=black;i++)//i =red 
   	for(j=red;j<=black;j++)//j=red  yellow blue 
   	if(i!=j) 
   	{
   		for(k=red;k<=black;k++) //k=red  yellow  blue white black;
   		if((k!=i)&&(k!=j))
   		{
   			n=n+1;  //n=1
   			printf("%-4d",n);
   			for(loop=1;loop<=3;loop++)
   			{
   				switch(loop)
   				{
   					case 1:pri=i;break;
   					case 2:pri=j;break;
   					case 3:pri=k;break;
   					default:break;
   				} 
   				switch(pri)
   				{
   					case red:printf("%-10s","red");break;
   					case yellow:printf("%-10s","yellow");break;
   					case blue :printf("%-10s","blue");break;
   					case white:printf("%-10s","white");break;
   					case black:printf("%-10s","black");break;
   					default break;
   				}
   			
   			 } 
   		printf("\n");
   		} 
   	}
   printf("\ntotal:%5d\n",n);
   return 0;
} 

9.7 typedef声明新类型名

1.先按照定义变量的方法写出定义体(如int i)
2.将变量名换成新类型名(例如:将i换成count)
3.在最前面加typedef(例如:typedef int count)
4.然后就可以用新类型去定义变量;

数组:
int a[100];
int num[100];
typedef int num[100];
........
num a;
字符指针:
char *p;
char *string;
typedef char *string;
string p;
整型:
int i;
int num;
typedef int num;
num a;
struct 
{
	int a;
	float b;
}a;
///
struct 
{
...
}num;
///
typedef struct
{
...
} num;
num a;意思就是定义一个结构体变量a;

定义一个tyoedef ;就是将原有变量名用一个新的变量名去代替,新的变量名她具有原来旧的变量名一样的结构特点;typedef只是代替原来已有的变量名,不能够定义一个全新的,未知结构的变量类型;
他有什么好处呢?
首先他修改起来很方便。你可以修改定义,那么后面所有你所定义的类型变量你都直接都随之改变。使用方便。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值