数据结构 链式存储 +

news2025/1/13 10:25:26

int DeleteLinkList(LinkList *list, char *name);
int ReviseLinkList(LinkList *list, char *name, DATATYPE data);
int DestroyLinkList(LinkList *list);
int InsertTailLinkList(LinkList *list, DATATYPE data);

​​​​​​​删除

修改​​​​​​​

 

销毁

​​​​​​​

 插入

 完整代码展示

#include <stdio.h>
#include "doulink.h"
#include <string.h>
int findbyname(DATATYPE*data,void* arg)
{
    return (0 == strcmp(data->name,(char*)arg));
}
int findbyage(DATATYPE*data,void* arg)
{
    return data->age == *(int*)arg;
}
int main()
{
    DATATYPE data[5]={
        {"zhangsan",'m',20,70},
        {"lisi",'f',21,60},
        {"wangmazi",'m',25,80},
        {"liubei",'f',30,85},
        {"caocao",'f',40,90},
    };

    DouLinkList* dl = CreateDouLinkList();

    InsertHeadLinkList(dl,&data[0]);
    InsertHeadLinkList(dl,&data[1]);
    InsertHeadLinkList(dl,&data[2]);

    ShowDouLinkList(dl,DIR_FORWARD);
    printf("-------------back---------------\n");
    ShowDouLinkList(dl,DIR_BACKWARD);
    printf("-------------find---------------\n");
    //    char want_name[]="lisi";
    //    //DouLinkNode* tmp = FindLinkList(dl,findbyname,want_name);
    //    int want_age = 25;
    //    DouLinkNode* tmp = FindLinkList(dl,findbyage,&want_age);
    //    if(NULL == tmp)
    //    {
    //        printf("can't find person ,name:%s\n",want_name);
    //    }
    //    else
    //    {

    //        printf("%s:%d\n",tmp->data.name,tmp->data.score);
    //    }

    //    RevertDouLinkList(dl);
    //    printf("-------------rev---------------\n");
    //    ShowDouLinkList(dl,DIR_FORWARD);
    //    DeleteLinkList(dl,findbyname,"lisi");
    //    printf("-------------del forware---------------\n");
    //    ShowDouLinkList(dl,DIR_FORWARD);
    //    printf("-------------back---------------\n");
    //    ShowDouLinkList(dl,DIR_BACKWARD);

    //    ModifyDouLinkList(dl,findbyname,"zhangsan",&data[3]);
    //    printf("-------------modify---------------\n");
    //    ShowDouLinkList(dl,DIR_FORWARD);

    InserPosDouLinkList(dl,&data[3],3);
    printf("-------------pos---------------\n");
    ShowDouLinkList(dl,DIR_FORWARD);
    printf("-------------back---------------\n");
    ShowDouLinkList(dl,DIR_BACKWARD);


    DestroyDouLinkList(&dl);

    printf("Hello World!\n");
    return 0;
}
#include "doulink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

DouLinkList *CreateDouLinkList()
{
    //DouLinkList dl ;
    DouLinkList* dl = (DouLinkList*)malloc(sizeof(DouLinkList));
    if(NULL == dl)
    {
        perror("CreateDouLinkList malloc");
        //exit(1);
        return NULL;
    }
    dl->head =NULL;
    dl->clen = 0 ;

    return dl;
}

int InsertHeadLinkList(DouLinkList *list, DATATYPE *data)
{
    DouLinkNode*newnode = malloc(sizeof(DouLinkNode));
    if(NULL == newnode)
    {
        perror("InsertHeadLinkList malloc");
        return 1;
    }
    memcpy(&newnode->data,data,sizeof(DATATYPE));
    newnode->next = NULL;
    newnode->prev= NULL;

    if(0==list->clen)//empty
    {
        list->head = newnode;
    }
    else
    {
        newnode->next = list->head;
        list->head->prev = newnode;
        list->head = newnode;
    }
    list->clen++;
    return 0;


}

int ShowDouLinkList(DouLinkList *list, DIRECT direct)
{
    int i = 0 ;
    DouLinkNode* tmp = list->head;
    if(direct==DIR_FORWARD)
    {
        for(i=0;i<GetSizeDouLinkList(list);i++)
        {
            printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
            tmp=tmp->next;
        }
    }
    else
    {
        while(tmp->next)
        {
            tmp=tmp->next;
        }
        for(i=0;i<GetSizeDouLinkList(list);i++)
        {
            printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
            tmp=tmp->prev;
        }
    }
    return 0;
}

int GetSizeDouLinkList(DouLinkList *list)
{
    return list->clen;
}

DouLinkNode *FindLinkList(DouLinkList *list, PFUN fun, void *arg)
{
    DouLinkNode* tmp = list->head;
    int size = GetSizeDouLinkList(list);
    int i =  0;
    for(i = 0 ;i<size;i++)
    {
        //if(0==strcmp(tmp->data.name))
        if(fun(&tmp->data,arg))
        {
            return tmp;
        }
        tmp= tmp->next;
    }
    return NULL;
}

int RevertDouLinkList(DouLinkList *list)
{
    int size = GetSizeDouLinkList(list);
    if(size<2)
    {
        return 0;
    }

    DouLinkNode* prev= NULL;
    DouLinkNode* tmp = list->head;
    DouLinkNode*next= tmp->next;
    while(1)
    {
        tmp->next = prev;
        tmp->prev = next;
        prev= tmp;
        tmp = next;
        if(NULL == tmp)
        {
            break;
        }
        next =next->next;
    }
    list->head = prev;
    return 0;
}

int DeleteLinkList(DouLinkList *list, PFUN fun, void *arg)
{
    if(NULL == list)
    {
        fprintf(stderr,"DouLinkList is null");
        return 1;
    }
    if(IsEmptyDouLinkList(list))
    {
        fprintf(stderr,"DouLinkList is empty");
        return 1;
    }
    DouLinkNode* ret = FindLinkList(list,fun,arg);
    if(NULL==ret)
    {
        fprintf(stderr,"DeleteLinkList error,cant find\n");
        return 1;
    }
    if(ret == list->head)
    {
        list->head = ret->next;
        list->head->prev = NULL;
    }
    else
    {
        if(ret->next)
        ret->next->prev = ret->prev;
        ret->prev->next = ret->next;
    }

    free(ret);
    list->clen--;
    return 0;
}

int IsEmptyDouLinkList(DouLinkList *list)
{
    return 0 == list->clen;
}

int ModifyDouLinkList(DouLinkList *list, PFUN fun, void *arg, DATATYPE *data)
{
    DouLinkNode* ret = FindLinkList(list,fun,arg);
    if(NULL == ret)
    {
        fprintf(stderr,"ModifyDouLinkList error,cant find\n");
        return 1;
    }
    memcpy(&ret->data,data,sizeof(DATATYPE));
    return 0;
}

int DestroyDouLinkList(DouLinkList **list)
{
    DouLinkNode* tmp=(*list)->head;
    while(tmp)
    {
    (*list)->head=(*list)->head->next;
    free(tmp);
    tmp = (*list)->head;

    }
    free(*list);
    (*list)= NULL;
    return 0;
}

int InserPosDouLinkList(DouLinkList *list, DATATYPE *data,int pos)
{
    if(pos<0 ||pos>GetSizeDouLinkList(list))
    {
        fprintf(stderr,"InserPosDouLinkList error,index error\n");
        return 1;

    }
    if(IsEmptyDouLinkList(list) || 0 == pos)
    {
        return InsertHeadLinkList(list,data);
    }
    else
    {
        DouLinkNode* tmp = list->head;
        tmp= list->head;
        DouLinkNode* newnode = (DouLinkNode*)malloc(sizeof(DouLinkNode));
        if(NULL == newnode)
        {
            perror("InserPosDouLinkList malloc");
            return 1;
        }
        memcpy(&newnode->data,data,sizeof(DATATYPE));
        newnode->prev = NULL;
        newnode->next = NULL;
        int i = pos-1;
        while(i--)
        {
            tmp=tmp->next;
        }
        newnode ->prev = tmp;
        newnode->next = tmp->next;//这时候都是NULL,如果是尾插入不走if

        if(tmp->next)
        {
        tmp->next->prev = newnode;//中间插入
        }
        tmp->next = newnode;
    }
    list->clen++;
    return 0;
}
#ifndef DOULINK_H
#define DOULINK_H
typedef struct{
    char name[32];
    char sex;
    int age;
    int score;
}DATATYPE;
typedef int (*PFUN)(DATATYPE*data,void* arg);//表示fun()中的参数书形式
typedef struct node {
    DATATYPE data;
    struct node *next,*prev;
}DouLinkNode;

typedef struct{
    DouLinkNode *head;
    int clen;
}DouLinkList;
typedef enum{DIR_FORWARD,DIR_BACKWARD}DIRECT;
DouLinkList* CreateDouLinkList();
int InsertHeadLinkList(DouLinkList *list, DATATYPE *data);
int ShowDouLinkList(DouLinkList *list,DIRECT direct);
int GetSizeDouLinkList(DouLinkList *list);
DouLinkNode *FindLinkList(DouLinkList *list, PFUN fun,void* arg);
int RevertDouLinkList(DouLinkList *list);
int DeleteLinkList(DouLinkList *list, PFUN fun,void* arg);
int IsEmptyDouLinkList(DouLinkList *list);
int ModifyDouLinkList(DouLinkList *list,PFUN fun,void* arg,DATATYPE *data);
int DestroyDouLinkList(DouLinkList **list);
int InserPosDouLinkList(DouLinkList *list,DATATYPE *data,int pos);
#endif // DOULINK_H

序表和链表 优缺点


    存储方式:
        顺序表是一段连续的存储单元
        链表是逻辑结构连续物理结构(在内存中的表现形式)不连续
    时间性能,
        查找 顺序表O(1)
             链表  O(n)
        插入和删除
            顺序表 O(n)
            链表   O(1)
            
    空间性能
            顺序表 需要预先分配空间,大小固定
            链表, 不需要预先分配,大小可变,动态分配
            
            
    循环链表
        简单的来说,就是将原来单链表中最有一个元素的next指针指向第一个元素或头结点,链表就成了一个环,头尾相连,就成了循环链表。circultlar linker list.
        
        注意非空表,和空表。多数会加入头结点。
        原来结束的条件是
        p->next != NULL ------->>>>> p-next != Head 
        
    双向链表
    double link list。
    
    typedef struct DulNode
    {
    
        ElemType date;
        struct DulNode *pri;
        sturct DulNode *next;
    }DulNode,*DuLinkList;
    

 习题

1)双向链表逆序

2)实现mplay的播放列表

main.c

#include <stdio.h>
#include "doulink.h"
#include <string.h>
#include "func.h"
#include <stdlib.h>
void show_menu( DouLinkList* dl)
{
    printf("1.show_list\n");
    printf("2.prev\n");
    printf("3.next\n");
    printf("4.end\n");
    char buf[10]={0};
    fgets(buf,sizeof(buf),stdin);
    int num = atoi(buf);
    switch (num) {
    case 1:
        ShowDouLinkList(dl,DIR_FORWARD);
        break;
    case 2:
        GetPrev(dl);
        break;
    case 3:
        Getnext(dl);
        break;
    case 4:
        exit(1);
        break;
    default:
        break;
    }
}
int main()
{
    DouLinkList* dl = CreateDouLinkList();
    do_ls("/home/linux",dl);

    ShowDouLinkList(dl,DIR_FORWARD);
    char *pathname=NULL;
    while(1)
    {
         show_menu(dl);
         pathname = GetCurrent(dl);
         printf("currnt play file:%s\n",pathname);

    }


    //atexit();
    printf("Hello World!\n");
    return 0;
}

doulink.c

#include "doulink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

DouLinkList *CreateDouLinkList()
{
    //DouLinkList dl ;
    DouLinkList* dl = (DouLinkList*)malloc(sizeof(DouLinkList));
    if(NULL == dl)
    {
        perror("CreateDouLinkList malloc");
        //exit(1);
        return NULL;
    }
    dl->head =NULL;
    dl->clen = 0 ;
    dl->currnet =NULL;

    return dl;
}

int InsertHeadLinkList(DouLinkList *list, DATATYPE *data)
{
    DouLinkNode*newnode = malloc(sizeof(DouLinkNode));
    if(NULL == newnode)
    {
        perror("InsertHeadLinkList malloc");
        return 1;
    }
    memcpy(&newnode->data,data,sizeof(DATATYPE));
    newnode->next = NULL;
    newnode->prev= NULL;

    if(0==list->clen)//empty
    {
        list->head = newnode;
    }
    else
    {
        newnode->next = list->head;
        list->head->prev = newnode;
        list->head = newnode;
    }
    list->clen++;
    return 0;


}

int ShowDouLinkList(DouLinkList *list, DIRECT direct)
{
    int i = 0 ;
    DouLinkNode* tmp = list->head;
    if(direct==DIR_FORWARD)
    {
        for(i=0;i<GetSizeDouLinkList(list);i++)
        {
            printf("%d %s\n",i,tmp->data.pathname);
            tmp=tmp->next;
        }
    }

    return 0;
}

int GetSizeDouLinkList(DouLinkList *list)
{
    return list->clen;
}

DouLinkNode *FindLinkList(DouLinkList *list, PFUN fun, void *arg)
{
    DouLinkNode* tmp = list->head;
    int size = GetSizeDouLinkList(list);
    int i =  0;
    for(i = 0 ;i<size;i++)
    {
        //if(0==strcmp(tmp->data.name))
        if(fun(&tmp->data,arg))
        {
            return tmp;
        }
        tmp= tmp->next;
    }
    return NULL;
}

int RevertDouLinkList(DouLinkList *list)
{
    int size = GetSizeDouLinkList(list);
    if(size<2)
    {
        return 0;
    }

    DouLinkNode* prev= NULL;
    DouLinkNode* tmp = list->head;
    DouLinkNode*next= tmp->next;
    while(1)
    {
        tmp->next = prev;
        tmp->prev = next;
        prev= tmp;
        tmp = next;
        if(NULL == tmp)
        {
            break;
        }
        next =next->next;
    }
    list->head = prev;
    return 0;
}



char *GetCurrent(DouLinkList *list)
{
    return list->currnet->data.pathname;
}

int GetPrev(DouLinkList *list)
{
    list->currnet = list->currnet->prev;
    if(NULL == list->currnet)
    {

        list->currnet = list->head;
        while(list->currnet->next)
        {
            list->currnet = list->currnet->next;
        }

    }
    return 0;

}

int Getnext(DouLinkList *list)
{
     list->currnet = list->currnet->next;
     if(NULL == list->currnet)
     {
           list->currnet = list->head;

     }
     return 0;
}

fun.c

#include "func.h"
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int do_ls(char *path,DouLinkList*dl)
{
    {

        DIR* dir = opendir(path);
           if(NULL == dir)
           {
               printf("opendir");
               return 1;
           }
            DATATYPE data;
           while(1)
           {
               struct dirent *info =  readdir(dir);
               //procintf("%s  %lu",info->d_name,info->d_ino);
               if(NULL == info)
               {
                   break;
               }
               if(strlen(info->d_name ) >3)// 1.flv  /home/linux/1.flv
               {
                   if(0==strcmp(&info->d_name[strlen(info->d_name)-3],"mp3")
                      ||0==strcmp(&info->d_name[strlen(info->d_name)-3],"flv")
                      ||0==strcmp(&info->d_name[strlen(info->d_name)-3],"mp4"))
                   {
                       bzero(&data,sizeof(data));

                       sprintf(data.pathname,"%s/%s",path,info->d_name);
                       //sprintf(song.songlist[song.total++],"%s/%s",path,info->d_name);
                       InsertHeadLinkList(dl,&data);


                   }
               }
               else
               {
                   continue;
               }
           }
           closedir(dir);
    }
     dl->currnet = dl->head;
    return 0;
}

fun.h

#ifndef FUNC_H
#define FUNC_H
#include "doulink.h"
int do_ls(char *path,DouLinkList*dl);

#endif // FUNC_H

doulink.h

#ifndef DOULINK_H
#define DOULINK_H
typedef struct{
    char pathname[512];
}DATATYPE;
typedef int (*PFUN)(DATATYPE*data,void* arg);
typedef struct node {
    DATATYPE data;
    struct node *next,*prev;

}DouLinkNode;

typedef struct{
    DouLinkNode *head;
    struct node *currnet;
    int clen;
}DouLinkList;
typedef enum{DIR_FORWARD,DIR_BACKWARD}DIRECT;
DouLinkList* CreateDouLinkList();
int InsertHeadLinkList(DouLinkList *list, DATATYPE *data);
int ShowDouLinkList(DouLinkList *list,DIRECT direct);
int GetSizeDouLinkList(DouLinkList *list);
DouLinkNode *FindLinkList(DouLinkList *list, PFUN fun,void* arg);
int RevertDouLinkList(DouLinkList *list);
char* GetCurrent(DouLinkList *list);
 int GetPrev(DouLinkList *list);
 int Getnext(DouLinkList *list);
#endif // DOULINK_H

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1952151.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Anaconda、Pytorch安装

Anaconda 打开 Anaconda 官网 https://www.anaconda.com/ 点击右上角的 Free Download 可以选择相应的型号进行下载 如果版本不合适&#xff0c;可以进入 anaconda 的历史版本官网选择适合本机 python 版本的 anaconda 进行下载&#xff1a; https://repo.anaconda.com/arc…

Django-3.3创建模型

创建模型&#xff08;models&#xff09;的时候&#xff0c; 1&#xff1a;我们需要这个模型是哪个文件下面的模型&#xff08;models&#xff09;&#xff0c;我们需要在配置文件中吧应用安装上&#xff08;安装应用&#xff1a;INSTALLED_APPS&#xff09; 2&#xff1a;找对…

【java计算机毕设】在线考试系统java MySQL ssm jsp maven项目设计代码前后端一体 寒暑假小组作业

目录 1项目功能 2项目介绍 3项目地址 1项目功能 2项目介绍 系统功能&#xff1a; ssm在线考试管理系统包括管理员、用户俩种角色。 管理员功能包括在线考试&#xff0c;参加考试&#xff0c;我的成绩&#xff0c;我的错题&#xff0c;资源大全&#xff0c;下载资源&#xf…

GUL图形化界面操作(下部)

目录 ​编辑 前言 Swing 窗口 注意点 新增的组件 进度条组件 开关按钮 多面板和分割面板 多面板 分割面板 ​编辑 选项窗口 对话框带三个选项是&#xff0c;否&#xff0c;取消。 对话框提示输入文本: 前言 修炼中&#xff0c;该篇文章为俺很久前的学习笔记 Swi…

Matlab类阿克曼车机器人运动学演示

v1是后驱动轮轮速&#xff0c; v2是转向角变化速度&#xff0c; 实际上我们只需要关注XQ&#xff0c; YQ和Phi的变化率。 通过这三项和时间步长&#xff0c; 我们就可以计算出变化量&#xff0c; 再结合初始值就能推断出每个时刻的值。 % 清理当前运行环境 % 清除所有变量 cle…

Windosw下Visual Studio2022编译FFmpeg(支持x264、x265、fdk-acc)

FFmpeg 7.0 版本移除了 6.0 之前已弃用的 API&#xff0c;无法向下兼容。所以编译的版本选择FFmpeg 6.1.1。 一、安装Visual Studio2022 可参考另外一篇文章&#xff1a;Windows安装Visual Studio2022 QT5.15开发环境_qt5.15.2 vs2022-CSDN博客 二、安装MSYS2 下载地址&…

企业创建百度百科有什么好处?

现如今&#xff0c;网络越来越发达&#xff0c;网络营销的方法百花齐放&#xff0c;对于企业和品牌来说,想要推广产品,就是提升知名度,让更多的人知道企业和品牌。 而百度现如今在中国的搜索市场上仍是巨头,而在百度上有权威,以及能提升企业知名度的就是百度百科了。 今天&…

Linux基础复习(二)

前言 本文介绍了一下Linux命令行基本操作及网络配置 一、 命令行提示含义 [当前用户主机名 工作目录]$ 若当前用户是root&#xff0c;则最后一个字符为# 否则&#xff0c;最后一个字符为$ 二、常用Linux命令及其解释 修改主机名 一般在创建一台主机后会使用hostname相关命…

《python程序语言设计》第6章13题 数列求和编写一个函数计算

正确代码 def sumNumber(integer_num):print(" i || m(i)")print("-"*30)a 0for i in range(1, integer_num 1):a i / (i 1)print("{:4d} || {:.4f}".format(i, a))sumNumber(20)结果如下

win11 安装 Gradle

一、win11 安装Gradle(7.5.1)&#xff1a; 1.1、下载二进制包 Gradle下载页面 1.2、配置环境变量 变量名&#xff1a;GRADLE_HOME 变量值&#xff08;二进制包解压路径&#xff09;&#xff1a;D:\develop-tool\gradle-7.5.1 变量名&#xff1a;GRADLE_USER_HOME 变量值&a…

qt总结--翻金币案例

完成了一个小项目的在qt5.15.2环境下的运行,并使用NSIS editNSIS打包完成.有待改进之处:增加计时功能,随机且能通关功能,过关后选择下一关功能.打包后仅仅有安装包有图标 安装后应用图标并未改变 在qt .pro中有待改进对qt的基本操作和帮助文档有了基本的认识.对C制作小游戏有了…

Linux-IO操作之fcntl 和 ioctl

fcntl函数&#xff0c;也就是file control&#xff0c;提供了对文件描述符的各种操作。另一个常见的控制文件描述符的属性和行为的系统调用是ioctl&#xff0c;而且ioctl比fcntl能够执行更多的控制。但是&#xff0c;对于控制文件描述符常见的属性和行为&#xff0c;fcntl函数是…

认证中心:基于cookie和session实现单点登陆

流程图 参数 不同域名之下&#xff08;不同父域名&#xff09; cookiesessionredis 流程追踪 用户访问系统1的受保护资源&#xff0c;系统1发现用户未登录&#xff0c;跳转至sso认证中心&#xff0c;并将自己的地址作为参数 sso认证中心发现用户未登录&#xff0c;将用户引…

Adobe Photoshop(PS) 2024软件下载(附下载链接)+PS教程

一、简介 Adobe Photoshop 2024&#xff08;简称PS2024&#xff09;是全球公认的专业图像处理和设计软件&#xff0c;它为摄影师、设计师和艺术家等创意工作者提供了强大的工具和功能。这款软件是Adobe Creative Cloud创意云桌面程序中心中的明星产品&#xff0c;凭借其出色的…

微信小程序之调查问卷

一、设计思路 1、界面 调查问卷又称调查表&#xff0c;是以问题的形式系统地记载调查内容的一种形式。微信小程序制作的调查问卷&#xff0c;可以在短时间内快速收集反馈信息。具体效果如下所示&#xff1a; 2、思路 此调查问卷采用服务器客户端的方式进行设计&#xff0c;服…

乐尚代驾八订单执行三

司机到达代驾终点&#xff0c;代驾结束了。结束代驾之后&#xff0c; – 获取额外费用&#xff08;高速费、停车费等&#xff09; – 计算订单实际里程&#xff08;实际与预估有偏差&#xff09; – 计算代驾实际费用 – 系统奖励 – 分账信息 – 生成最终账单 计算订单…

【计算机网络】RIP路由协议实验

一&#xff1a;实验目的 1&#xff1a;掌握在路由器上配置RIPv2。 二&#xff1a;实验仪器设备及软件 硬件&#xff1a;RCMS交换机、网线、内网网卡接口、Windows 2019操作系统的计算机等。具体为&#xff1a;三层交换机1台、路由器2台。 软件&#xff1a;wireshark软件、记…

Qwen2-Audio:对话式AI突破,让你“声”临其境

阿里巴巴最新推出的音频处理模型Qwen2-Audio&#xff0c;不仅能直接用语音聊天&#xff0c;还能像一位专业的听觉大师一样分析各种声音&#xff0c;功能强大得令人难以置信。 Qwen2-Audio可以通过语音聊天和音频分析两种方式与用户互动&#xff0c;用户无需区分这两种模式&…

请问C语言到底允不允许动态定义数组大小?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「c语言的资料从专业入门到高级教程」&#xff0c;点个关注在评论区回复“666”之后私信回复“666”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 按照谭浩强的第五版C程序设…

vue实现电子签名、图片合成、及预览功能

业务功能&#xff1a;电子签名、图片合成、及预览功能 业务背景&#xff1a;需求说想要实现一个电子签名&#xff0c;然后需要提供一个预览的功能&#xff0c;可以查看签完名之后的完整效果。 需求探讨&#xff1a;后端大佬跟我说&#xff0c;文档我返回给你一个PDF的oss链接…