C语言简单链表详细步骤详解

                 +《链表——>小阿豪带你写链表》!!!!进入正文
1.首先,先想好自己要创建的链表格式以及最后的的显示界面!!!
2.主函数尽量放到后面写,前面写功能函数,在调用主函数之前要声明一下!!
3.先写链表主结构体,再写成员结构体,将成员结构体嵌入主结构体!!!
~4.可以给你所需要的功能创建一个菜单,用switch-case语句实现功能!!!
5.注意功能函数的放置次序,要不然会报错,必须声明!!!

干货开始!!-》》》此处为伪代码内容
例:
0.先定义好你的成员结构体和主结构体//每一步都会用到!!!!

struct student//定义学生信息系统结构体将其放到数据域中进行相应操作
{
    char name[20];
    int num;
    int math;
};
struct node {             
    struct student data;             //数据域,用来存放数据
    struct node* next;    //指针域,用来存放下一个结构体的地址
};

1.struct node开始创建一个主结构体,//一个链表结构体至少有两个域->

 //struct student data;             //数据域,用来存放数据
    //struct node* next;    //指针域,用来存放下一个结构体的地址

2.struct node* createList()//面向对象结构体类型//开始创建一个链表,创建链表前先创建一个空的指向指针节点,这是给链表节点进行初始化!!

    //该函数功能创建一个链表,给出一个链表开头空节点NULL
    //使用malloc函数去动态申请内存空间,标识符定义为newList(自己随便想一个标识符去定义,是给该链表申请一个结构体类型的内存)//struct node* newList = (struct node*)malloc(sizeof(struct node));
   //这一步不必写成员结构体,因为头空节点就是用来存放头节点的地址的,利用头插法每当插入一个元素就让头空节点去指向这个插入节点的地址(即这个新的头节点地址)!!!!
   //newList->next = NULL;//让该链表头空节点指向0地址NULL,下一次创建好链表头节点(创建链表节点,给链表第一个数据节点为NULL)后将头节点地址赋给它!!!
   //因为函数面向对象,创建完成后要return返回newList;
   //头空节点创建完成》》》》每当做完一个功能试运行调试!!!

3.创建链表的第一个数据节点,并让头空节点指向它(注意头空节点永远指向头节点地址,临时操作改变之后也一定要连接回去)!!

  //将要创建的成员结构体类型用开始结构体创建时候的标识符号名形参传入
     //同样malloc函数去申请空间(这次的内存是给成员结构体申请的!),将该函数放在循环中即可连续添加成员!!!
     struct node* newNode = (struct node*)malloc(sizeof(struct student));
     //newNode->data=data;//让链表的data成员去标识你自己定义的成员结构体(即数据域!)
     //
     //newNode->next = NULL;//指针为空//尾巴节点的next永远指向空(即前闭后开)!!//该节点用头插法插入的话等下一个节点插入与他相连接之后就没它什么事了!!
     //因为函数面向对象,插入完成之后同样return返回要放在newList里面的这个节点newnode;

4.打印函数提前写//为了调试方便》》》

 //void printfList(struct node* headNode)//把链表LIst传入该函数进行打印
   //struct node* pMove = headNode->next;定义一个主要结构体类型变量pMove把headNode(即->头空节点只不过是定义形参headNode来接收了newList)把头空节点的next(这个next里面存放的就是第一个节点的地址)赋给pMove,让他从第一个节点开始打印
   //自行设置要打印的格式,//pMove = pMove->next;将下一个节点的地址赋给当前游标pMove//放在循环里面让它一个一个成员遍历打印!!!
   //配合if语句调用主函数即可返回菜单!!!

5.插入内容

  我给你写的直观一点,插入函数和插入内容没有放在一个函数中->认真看!!!
         1.先写一个插入函数去调用链表节点创建函数createNode()插入节点
                 void charu(struct node* headNode, struct student data)
               //面向过程函数,使用形参传入要插的链表和要插入的数据
                   struct node* newNode = createNode(data);//调用创建节点函数去给要插入的数据申请一个位置来存放插入数据!!!
                // newNode->next = headNode->next; 把头空节点的next的新插入节点相连!!!
                //headNode->next = newNode;再把新节点地址放到头空节点的next里面去!!!!
         2.struct node* List = createList();//创建链表List;//在开始写添加成员函数时先定义一下你在整个过程中要用到的链表,此步调用创建链表函数来做!!!!!
           // 这步写添加成员函数,利用循环调用插入函数每当输入好一个成员信息就按回车连接到链表里面去作为新的头节点,每次缓冲区都留有一个回车符用setbuf(stdin,NULL);函数来清空缓冲区

6.删除内容!!!

  // void shanchu(struct node* headNode, int num1)//面向过程void类型,创建删除函数
       //struct node* posnode = headNode->next;/*posnode相当于一个主的临时结构体变量指针,把头节点指向指针地址给临时结构体变量让他从第一个开始循环*/
       //struct node* posnodeFront = headNode;//同时也要定义一个主的结构体类型变量指针来存放主的临时结构体变量地址;
       //先判断头空指针的next是否指向NULL,是则链表为空,否则去进入到循环遍历,找到该成员则把该节点next的值赋给它前一个结点的next,并用free();函数去释放掉要删除节点的内存
       //在循环中寻找每当遍历下一个成员时,先posnodeFront = posnode;先把当前临时节点指针地址给前一个,后posnode = posnodeFront->next;再把给过去的next里面存放的下一个结点的地址给当前临时节点指针,进而去循环!!!
       //注意指针必须赋的是地址,而不是具体的值!!!!!

7.修改内容与第六步同理只不过不释放空间不改变指针的连接,找到成员之后改掉要修改的对应成员体结构中的内容就好了!!!!!

8.主函数开始写好框架,每添加一个功能函数就放到选择函数里面去!!!!

》》》》》接下来看实例代码》》建议在codeblocks中运行,无报错!!!
代码1:学生信息管理系统——>

```cpp
#include<stdio.h>
#include<stdlib.h>
void choice();
int main();
void shanchu(struct node* headNode, int num1);
void menu()
{
    printf("\t\t\t***学生信息管理系统***\n");
    printf("\t\t\t       -》菜单《-     \n");
    printf("\t\t\t**********************\n");
    printf("\t\t\t*     1.插入内容     *\n");
    printf("\t\t\t*     2.显示内容     *\n");
    printf("\t\t\t*     3.删除内容     *\n");
    printf("\t\t\t*     4.修改内容     *\n");
    printf("\t\t\t*     5.退出系统     *\n");
    printf("\t\t\t*                    *\n");
    printf("\t\t\t*   制作人:小阿豪   *\n");
    printf("\t\t\t*    ^-^  ^-^  ^-^   *\n");
    printf("\t\t\t**********************\n\n");

}

struct student//定义学生信息系统结构体将其放到数据域中进行相应操作
{
    char name[20];
    int num;
    int math;
};
struct node {             //一个链表结构体至少有两个域
    struct student data;             //数据域,用来存放数据
    struct node* next;    //指针域,用来存放下一个结构体的地址
};

//节点初始化
struct node* createList()//面向对象结构体类型//开始创建一个链表,创建链表前先创建一个空的指向指针节点
{
    struct node* newList = (struct node*)malloc(sizeof(struct node));
   // newList->data = struct student data;
    newList->next = NULL;
    return newList;
};
//创建链表节点,给链表第一个数据节点
struct node* createNode(struct student data)//面向对象结构体类型
{
    struct node* newNode = (struct node*)malloc(sizeof(struct student));
    newNode->data=data;//迭代器???
    newNode->next = NULL;//指针为空
    return newNode;
};

//打印内容
void printfList(struct node* headNode)//面向过程void类型
{
    struct node* pMove = headNode->next;
    printf("学号\t姓名\t数学成绩\n");//制表输出
    while (pMove)
    {
        printf("%d\t%s\t%d\n",pMove->data.num, pMove->data.name, pMove->data.math);
        pMove = pMove->next;
    }
    printf("\n");
    getchar();
    printf("是否要返回菜单(Y)退出(N)\n");
    char ok;
    scanf("%c",&ok);
    if(ok=='Y'||ok=='y'){
        main();
    }
    else exit(1);
}

//插入函数
void charu(struct node* headNode, struct student data)//面向过程void类型
{
    struct node* newNode = createNode(data);
    newNode->next = headNode->next;//headNode->next存放的是第一个节点的地址,
    headNode->next = newNode;
};
struct node* List = createList();//创建链表List;
  struct student info;//定义一个struct student变量info
//插入内容
void zengjia()
{

        while(1)//给一个循环插入
        {
            printf("请输入学生的姓名 学号 数学成绩:");
            getchar();
            scanf("%s%d%d",info.name,&info.num,&info.math);
            charu(List,info);//到链表里面头插法插入一个student结构体
            printf("插入成功!\n");
            printf("是否要继续(Y),返回菜单输入M\n");
            setbuf(stdin,NULL);//清空缓冲区
            int choice=getchar();//是否要继续插入数据
            if(choice=='m'||choice=='M'){
               main();
            }
        }
}

//删除内容
void shanchu(struct node* headNode, int num1)//面向过程void类型
{
    struct node* posnode = headNode->next;/*posnode相当于一个临时结构体变量,
                                          把头节点指向指针地址给临时结构体变量让他从第一个开始循环*/
    struct node* posnodeFront = headNode;
    if (headNode->next == NULL) {          //用头指针判读链表是否为空(即headnext->是否为NULL
        printf("链表为空不能删除!\n");
    }
    else {
        while (posnode->data.num != num1) {  //循环条件是否循环到了要删除的节点
            posnodeFront = posnode;         //posnode相当于一个临时结构体变量,把挨着找的结构体地址给这个临时的结构体
            posnode = posnodeFront->next;   /*再把之前那个结构体里面的下一个结构体的地址
                                               给posnode让它成为当前结构体,好在下一轮继续循环下一个结构体变变量*/
            if (posnode == NULL) {
                printf("没有找到该学生信息!\n");
                system("pause");
                getchar();
                printf("是否要返回菜单(Y)退出(N)\n");
                char ok;
                scanf("%c",&ok);
                if(ok=='Y'||ok=='y'){
                    main();
                }
                else exit(1);
            }
        }
        posnodeFront->next = posnode->next;//让最后一个结构体指针指向NULL
        free(posnode);//释放要删除节点的内存
        printf("删除成功!\n");
    }
    printf("是否要返回菜单(Y)退出(N)\n");
    char ok;
    scanf("%c",&ok);
    if(ok=='Y'||ok=='y'){
        main();
    }
    else exit(1);
};
//修改内容
void xiugai(struct node* headNode, int num1)//面向过程void类型
{
    struct node* posnode = headNode->next;/*posnode相当于一个临时结构体变量,
                                          把头节点指向指针地址给临时结构体变量让他从第一个开始循环*/
    struct node* posnodeFront = headNode;
    if (headNode->next == NULL) {          //用头指针判读链表是否为空(即headnext->是否为NULL
        printf("链表为空不能修改!\n");
    }
    else {
        while (posnode->data.num != num1) {  //循环条件是否循环到了要删除的节点
            posnodeFront = posnode;         //posnode相当于一个临时结构体变量,把挨着找的结构体地址给这个临时的结构体
            posnode = posnodeFront->next;   /*再把之前那个结构体里面的下一个结构体的地址
                                               给posnode让它成为当前结构体,好在下一轮继续循环下一个结构体变变量*/
            if (posnode == NULL) {
                printf("没有找到该学生信息!\n");
                system("pause");
                getchar();
                printf("是否要返回菜单(Y)退出(N)\n");
                char ok;
                scanf("%c",&ok);
                if(ok=='Y'||ok=='y'){
                    main();
                }
                else exit(1);
            }
        }
    printf("该学生信息为:\t%d\t%s\t%d\n",posnode->data.num,posnode->data.name,posnode->data.math);
    printf("请输入修改之后学生的姓名 学号 数学成绩:");
    scanf("%d%s%d",&posnode->data.num,posnode->data.name,&posnode->data.math);
//        posnode->data.name=pos.name;
//        posnode->data.num=pos.num;
//        posnode->data.math=pos.math;
        printf("修改成功!\n");
        system("pause");
        main();
    }
};


//选择功能
void choice()
{
    int xuhao;
    printf("请输入你选择的序号:");
    scanf("%d",&xuhao);
    switch(xuhao)
    {
    case 1:
        zengjia();
        break;
    case 2:
         printfList(List);//打印函数打印链表
        break;
    case 3:
    printf("请输入你要删除的学生编号:");
    scanf("%d",&info.num);//直接放到了一个结构体中将数字
    shanchu(List,info.num);//删除链表里学号为num的那个人
        break;
    case 4:
    printf("请输入你要修改信息的学生编号:");
    scanf("%d",&info.num);//直接放到了一个结构体中将数字
    xiugai(List,info.num);
        break;
    case 5:
        printf("感谢您的使用!下次再见 》》》\n");
        exit(1);
        break;
    default:
        printf("没有该功能!\n");
        break;
    }
}

int main()
{

    //struct node* posnode;
    menu();
    choice();
    system("pause");//按任意键继续
    return 0;
}

```cpp
代码2:洗脚城VIP会员系统
#include<stdio.h>
#include<stdlib.h>
int main();
void meun()
{
    printf("\t\t\t              >洗脚城VIP会员系统<                \n");
    printf("\t\t\t*************************************************\n");
    printf("\t\t\t*                                               *\n");
    printf("\t\t\t*                  1.添加会员                   *\n");
    printf("\t\t\t*                  2.显示会员                   *\n");
    printf("\t\t\t*                  3.会员充值                   *\n");
    printf("\t\t\t*                  4.解除会员                   *\n");
    printf("\t\t\t*                  5.退出系统                   *\n");
    printf("\t\t\t*                              制作人:小阿豪   *\n");
    printf("\t\t\t*************************************************\n");
}

 struct member       //成员信息结构体
 {
     int num;
     char name[20];
     int money=0;
 };
 struct xjc            //洗脚城结构体
 {
     struct member data;
     struct xjc *next;  //指向下一个结构体

 };
 struct xjc *createList()//洗脚城迭代器,创建链表,给予一个头部空节点
 {
     struct xjc *newList=(struct xjc*)malloc(sizeof(struct xjc));
     newList->next=NULL;
     return newList;

 };

 struct xjc *createNode(struct member data)//会员信息迭代器,创建链表的第一个节点,将其连到空节点//信息都是存在这里面,所以要有形参接收
 {
     struct xjc *newNode=(struct xjc*)malloc(sizeof(struct xjc));
     newNode->data=data;
     newNode->next=NULL;
     return newNode;
 };
 struct xjc *List=createList();

 //打印函数
 void printfList(struct xjc *headNode)
 {
     struct xjc *_Move=headNode->next;//next存放的为第一个节点
     printf("\t会员编号\t姓名\t余额\n");
     if(_Move==NULL){
        printf("\n\t还没有添加会员信息哦!!\n");
     }else{
         while(_Move){
                printf("\t%d\t\t%s\t%d\n",_Move->data.num,_Move->data.name,_Move->data.money);
                _Move=_Move->next;
         }
     }
     printf("\n");
     getchar();
     printf("是否要返回菜单(Y)退出(N)\n");
     char ok;
     scanf("%c",&ok);
     if(ok=='Y'||ok=='y'){
        main();
    }
     else exit(1);
 }

 //插入函数

 void charu(struct xjc*headNode,struct member data)
 {
     struct xjc*newnode=createNode(data);
     newnode->next=headNode->next;
     headNode->next=newnode;
 }

 struct member info;
 //插入会员
 void zengjia()
 {
     while(1){
         printf("请输入你要添加的会员编号 姓名 金额:");
         scanf("%d%s%d",&info.num,info.name,&info.money);
         charu(List,info);
         printf("添加成功!\n");
         getchar();
         printf("是否要返回菜单(Y)继续添加(N)\n");
         char ok;
         scanf("%c",&ok);
         getchar();
         if(ok=='y'||ok=='Y'){
            main();
         }else continue;
     }


 }

//会员充值
void chongzhi(struct xjc*headNode,int tnum,int tmoney)
{
    struct xjc*posNode=headNode->next;
    struct xjc*posNodefront=posNode;
    if(posNode==NULL){
        printf("还没有添加会员!\n");
        main();
    }else{
            while(posNode->data.num!=tnum){
                posNodefront=posNode;
                posNode=posNodefront->next;
                 if (posNode == NULL) {
                    printf("没有找到该会员信息!\n");
                    system("pause");
                    getchar();
                    printf("是否要返回菜单(Y)退出(N)\n");
                    char ok;
                    scanf("%c",&ok);
                    if(ok=='Y'||ok=='y'){
                        main();
                    }
                    else exit(1);
            }
        }
            posNode->data.money=posNode->data.money+tmoney;
            printf("充值成功!\n");

        printf("是否要返回菜单(Y)退出(N)\n");
        setbuf(stdin,NULL);
        char ok;
        scanf("%c",&ok);
        if(ok=='y'||ok=='Y'){
                printf("iavdj\n");
            main();
        }else exit(1);
    }
}

//删除会员
void shanchu(struct xjc*headNode,int num)
{
    struct xjc*posnode=headNode->next;
    struct xjc*posnodefront=headNode;
    if(headNode->next==NULL){
        printf("还未添加会员,不能删除!\n");
    }else{
        while(posnode->data.num!=num){
            posnodefront=posnode;//把地址给另一个变量
            posnode=posnodefront->next;//让临时变量指向他自己里面存的下一个域的地址
            if(posnode=NULL){
                printf("没有找到该会员的信息!\n");
                system("pause");
                getchar();
                printf("是否要返回菜单(Y)退出(N)\n");
                char ok;
                scanf("%c",&ok);
                if(ok=='Y'||ok=='y'){
                    main();
                }
                else exit(1);
            }
        }
        posnodefront->next=posnode->next;
        free(posnode);
        printf("解除会员成功!\n");
    }
    printf("是否要返回菜单(Y)退出(N)\n");
    setbuf(stdin,NULL);
    char ok;
    scanf("%c",&ok);
    if(ok=='Y'||ok=='y'){
        main();
    }
    else exit(1);
}
void choice()
{
    printf("请输入你要选择的功能序号:");
    int xuhao;
    scanf("%d",&xuhao);
    switch(xuhao)
    {
    case 1:
        zengjia();
        break;
    case 2:
        printfList(List);
        break;
    case 3:
        printf("请输入你要充值的会员编号 充值金额:");
        int tmoney;
        int tnum;
        scanf("%d%d",&tnum,&tmoney);
        chongzhi(List,tnum,tmoney);
        break;
    case 4:
        int num;
        printf("请输入你要解除的会员编号:");
        scanf("%d",&num);
        shanchu(List,num);
        break;
    case 5:
        exit(1);
        break;
    default:
        printf("没有该功能!\n");
        break;
    }

}

int main()
{
    meun();
    choice();
    system("pause");
    return 0;
}

》》》》》干货到此结束》》》请多多支持与分享》》
作者:爱写代码的阿豪吖!!

二.内核链表 内核链表是一种链表,Linux内核中的链表都是用这种形式实现的 1.特性 内核链表是一种双向循环链表,内核链表的节点节点结构中只有指针域 使用内核链表的时候,将内核链表作为一个成员放入到一个结构体中使用 我们在链表中找到内核链表结构的地址,通过这个地址就可以找到外部大结构体的地址,通过大结构体就可以访问其中的成员 优势: 内核链表突破了保存数据的限制,可以用内核链表来保存任何数据(使用一种链表表示各种类型的数据,通用性很强) 内核链表中只有指针域,维护起来更加方便,效率更高 2.使用 内核链表在内核中已经被实现,我们只需要调用其接口直接使用即可 内核链表的实现代码在内核源代码的list.h文件中 3.源代码分析 (1)节点结构: struct list_head { struct list_head *next, *prev;//前置指针 后置指针 }; (2)初始化 #define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) (3)插入 //从头部插入 static inline void list_add(struct list_head *new, struct list_head *head)//传入要插入的节点和要插入的链表 { __list_add(new, head, head->next); } //从尾部插入 static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } (4)通过节点找到外部结构体的地址 //返回外部结构体的地址,第一个参数是节点地址,第二个参数是外部结构体的类型名,第三个参数是节点在外部结构体中的成员名 #define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) (5)遍历内核链表 //遍历内核链表 #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); \ pos = pos->next) //安全遍历内核链表 #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) 二.内核链表 内核链表是一种链表,Linux内核中的链表都是用这种形式实现的 1.特性 内核链表是一种双向循环链表,内核链表的节点节点结构中只有指针域 使用内核链表的时候,将内核链表作为一个成员放入到一个结构体中使用 我们在链表中找到内核链表结构的地址,通过这个地址就可以找到外部大结构体的地址,通过大结构体就可以访问其中的成员 优势: 内核链表突破了保存数据的限制,可以用内核链表来保存任何数据(使用一种链表表示各种类型的数据,通用性很强) 内核链表中只有指针域,维护起来更加方便,效率更高 2.使用 内核链表在内核中已经被实现,我们只需要调用其接口直接使用即可 内核链表的实现代码在内核源代码的list.h文件中 3.源代码分析 (1)节点结构: struct list_head { struct list_head *next, *prev;//前置指针 后置指针 }; (2)初始化 #define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) (3)插入 //从头部插入 static inline void list_add(struct list_head *new, struct list_head *head)//传入要插入的节点和要插入的链表 { __list_add(new, head, head->next); } //从尾部插入 static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } (4)通过节点找到外部结构体的地址 //返回外部结构体的地址,第一个参数是节点地址,第二个参数是外部结构体的类型名,第三个参数是节点在外部结构体中的成员名 #define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) (5)遍历内核链表 //遍历内核链表 #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); \ pos = pos->next) //安全遍历内核链表 #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) 二.内核链表 内核链表是一种链表,Linux内核中的链表都是用这种形式实现的 1.特性 内核链表是一种双向循环链表,内核链表的节点节点结构中只有指针域 使用内核链表的时候,将内核链表作为一个成员放入到一个结构体中使用 我们在链表中找到内核链表结构的地址,通过这个地址就可以找到外部大结构体的地址,通过大结构体就可以访问其中的成员 优势: 内核链表突破了保存数据的限制,可以用内核链表来保存任何数据(使用一种链表表示各种类型的数据,通用性很强) 内核链表中只有指针域,维护起来更加方便,效率更高 2.使用 内核链表在内核中已经被实现,我们只需要调用其接口直接使用即可 内核链表的实现代码在内核源代码的list.h文件中 3.源代码分析 (1)节点结构: struct list_head { struct list_head *next, *prev;//前置指针 后置指针 }; (2)初始化 #define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) (3)插入 //从头部插入 static inline void list_add(struct list_head *new, struct list_head *head)//传入要插入的节点和要插入的链表 { __list_add(new, head, head->next); } //从尾部插入 static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } (4)通过节点找到外部结构体的地址 //返回外部结构体的地址,第一个参数是节点地址,第二个参数是外部结构体的类型名,第三个参数是节点在外部结构体中的成员名 #define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) (5)遍历内核链表 //遍历内核链表 #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); \ pos = pos->next) //安全遍历内核链表 #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) C语言下的单链表,可以增加,删除,查找,销毁节点。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值