【C项目】无头单向不循环链表

简介:本系列博客为C项目系列内容,通过代码来具体实现某个经典简单项目
适宜人群:已大体了解C语法同学
作者留言:本博客相关内容如需转载请注明出处,本人学疏才浅,难免存在些许错误,望留言指正
作者博客链接:睡觉待开机

下面是本项目的大体思路梳理:
在这里插入图片描述

全部接口一览:

在这里插入图片描述

void SLTPrint(SLTNode* phead);//打印
void SLTPushBack(SLTNode** pphead,SLTDateType x);//尾插
void SLTPushiFront(SLTNode** pphead, SLTDateType x);//头插
void SLTPopBack(SLTNode** pphead);//尾删
void SLTPopFront(SLTNode** pphead);//头删
void SLTInsert(SLTNode** pphead,SLTNode* pos,SLTDateType x);//任意位置之前插入
SLTNode* SLTFind(SLTNode** pphead, SLTDateType x);//查找接口
void SLTInsertAfter(SLTNode* pos, SLTDateType x);//任意位置之后插入
void SLTErase(SLTNode** pphead, SLTNode* pos);//删除pos指向的节点
void SLTEraseAfter(SLTNode* pos);//删除pos指向之后的节点
void SLTDestroy(SLTNode** pphead);//销毁链表接口

1.创建链表的结构体

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

//定义单链表结构体
#define SLTDateType int
typedef struct SListNode
{
	SLTDateType date;//每个节点的数据
	struct SListNode* next;//每个节点存储下一个节点的地址
}SLTNode;

2.打印链表的接口实现

首先制造一些节点并进行相连操作
在这里插入图片描述
打印函数实现的思路:
在这里插入图片描述
在这里插入图片描述

void SLTPrint(SLTNode* phead)
{
	//定义一个新的指针
	SLTNode* pcur = phead;

	//循环打印即可,什么时候停止?pcur不指向空便不停止
	while (pcur)
	{
		//打印数据
		printf("%d->", pcur->date);
		//更新指针
		pcur = pcur->next;
	}

	//为了完善,我给最后也加一个NULL
	printf("NULL\n");
}

3.尾插接口实现

思路:定义一个新指针,找到原链表的尾节点,找到了接上即可。
在这里插入图片描述
这里为什么要分类进行讨论?这由思路决定的,因为如果是空链表的情况下,ptail->next根本就是错误的,因为不存在。
在这里插入图片描述
在这里插入图片描述
新空间开辟接口:
在这里插入图片描述

void SLTPushBack(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);

	//申请一块新的空间
	SLTNode* newnode = SLTBuyNode(x);
	//分两种情况
	//链表为空
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else//链表不为空
	{
		SLTNode* ptail = *pphead;//用于找到链表的尾节点
		while (ptail->next)
		{
			ptail = ptail->next;
		}//找到尾节点
		ptail->next = newnode;//给他接上
	}
}

SLTNode* SLTBuyNode(SLTDateType x)
{
	//申请一块新的空间
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	//放内容
	newnode->date = x;
	newnode->next = NULL;
	//返回地址
	return newnode;
}

4.头插接口实现

思路:
在这里插入图片描述
在这里插入图片描述
尾插需要分情况讨论而头插怎么不需要呢?还是思路决定的,这个思路没有用到ptail->next所以就不需要考虑空链表的情况

void SLTPushiFront(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);

	//申请一块新的空间
	SLTNode* newnode = SLTBuyNode(x);
	//把原来第一个结点的地址交给新节点的next
	newnode->next = *pphead;
	*pphead = newnode;//把头部指针更新一下
}

5.尾删接口实现

思路:
在这里插入图片描述
在这里插入图片描述
这里为什么要分只有一个节点和多个节点的不同情况?因为涉及到prev问题如果是只有一个节点,ptail指向第一个节点,那prev指针指向哪里?所以要对只有一个节点的链表单独进行处理。

void SLTPopBack(SLTNode** pphead)
{
	//检验
	assert(pphead);//原本的指针不能是空
	assert(*pphead);//传过来的不能是空指针给我删除啊

	//删除
	//这里分两种情况
	//1.只有一个节点的情况
	if (*pphead == NULL)
	{
		free(*pphead);
		*pphead = NULL;
		return;
	}
	else//多个节点的情况
	{
		//需要找到最后一个节点和倒数第二个节点
		//最后一个节点是为了释放空间
		//倒数第二个节点是为了把他的next部分置为空
		SLTNode* ptail = *pphead;
		SLTNode* prev = *pphead;
		while (ptail->next)
		{
			prev = ptail;
			ptail = ptail->next;
		}

		//第二个节点next置为空
		prev->next = NULL;
		//销毁第一个节点
		free(ptail);
		ptail = NULL;
	}
}

6.头删接口的实现

思路:
在这里插入图片描述
在这里插入图片描述

void SLTPopFront(SLTNode** pphead)
{
	//检验
	assert(pphead);//检验你别给我传个空
	assert(*pphead);//检验链表不为空,空链表删除什么?

	//开始准备删除
	SLTNode* next = (*pphead)->next;//记录一下要接上的地址
	free(*pphead);//释放第一个节点
	*pphead = next;
}

7.查找接口实现

查找接口是做什么的呢?找一个节点的地址的。
思路实现:
在这里插入图片描述
在这里插入图片描述

SLTNode* SLTFind(SLTNode** pphead, SLTDateType x)
{
	//检查
	assert(pphead);//别传空指针进来
	//这里可以传空链表吗?可以!顶多找不到给你返回一个NULL嘛

	//遍历链表
	SLTNode* pcur = *pphead;
	while (pcur)//当pcur找到NULL时候就会停止
	{
		if (pcur->date == x)
		{
			return pcur;//满足条件,返回该节点的地址
		}
		pcur = pcur->next;//更新指针
	}
	//如果什么都没有找到的话,是不是会不太合适\
	// 所以我们规定如果没有找到,返回NULL地址

	return NULL;
}

8.在指定位置之前插入数据

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

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{
	//检验
	assert(pphead);//传入地址不得为空
	assert(pos);//pos不得为空
	assert(*pphead);//要加上链表不得为空,\
	这是因为pos是链表的一个节点的地址,如 \
    果链表不存在,那么pos也会不存在

	//这里要分情况进行处理
	//1.pos刚好是头节点
	if (pos == *pphead)
	{
		//直接调用头插
		SLTPushiFront(pphead,x);
		return;
	}
	else//2.如果pos不是头节点
	{
		SLTNode* prev = *pphead;
		//让prev找到pos之前的节点的地址
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		
		SLTNode* newnode = SLTBuyNode(x);//申请空间
		prev->next = newnode;//把新空间链接到我们前一个节点
		newnode->next = pos;//把新空间与pos指向的空间链接在一起
	}
}

9.在指定位置之后插入数据的接口实现

思路:
在这里插入图片描述
在这里插入图片描述
思考:上面说的关联新节点的错误是如何引起的呢?
答:因为新节点的后面的节点的地址表示是靠的pos->next

void SLTInsertAfter(SLTNode* pos, SLTDateType x)//之后
{
	//检查
	assert(pos);
	
	//申请空间
	SLTNode* newnode = SLTBuyNode(x);

	//关联新节点的错误写法,原因:pos值的改变
	//pos->next = newnode;
	//newnode->next = pos->next;

	//关联新节点的正确写法:
	//先接后面,再接前面
	newnode->next = pos->next;
	pos->next = newnode;

}

10.删除指定位置的节点

思路:
在这里插入图片描述

在这里插入图片描述

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	//检查
	assert(pphead);//不得传空
	assert(*pphead);//不得为空链表
	assert(pos);

	//pos刚好是头节点的情况,头删
	if (*pphead == pos)
	{
		//头删
		SLTPopFront(pphead);
		return;
	}
	//如果不是头节点
	else {
		//找到pos之前的节点
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}

}

11.删除指定位置之后的节点接口实现

思路:
在这里插入图片描述
在这里插入图片描述

void SLTEraseAfter(SLTNode* pos)
{
	//检查
	assert(pos);//传过来的地址不可以为空
	assert(pos->next);//传过来的地址的下一个地址不得为空

	SLTNode* del = pos->next;//记录要删除的节点的地址
	pos->next = pos->next->next;//更新pos中next的地址
	free(del);//释放空间
	del = NULL;//临时指针及时置为空
}

12.销毁链表接口

思路:
在这里插入图片描述
在这里插入图片描述

void SLTDestroy(SLTNode** pphead)
{
	assert(pphead);//传过来的指针不得为空
	assert(*pphead);//链表不得为空,空链表不用销毁

	//创建遍历指针
	SLTNode* pcur = *pphead;
	//循环销毁
	while (pcur)//啥时候停止?pcur指向NULL
	{
		SLTNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	//最后把头指针也置为NULL
	*pphead = NULL;
}

全部代码合集

//SList.h
#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>

//定义单链表结构体
#define SLTDateType int
typedef struct SListNode
{
	SLTDateType date;//每个节点的数据
	struct SListNode* next;//每个节点存储下一个节点的地址
}SLTNode;


void SLTPrint(SLTNode* phead);//打印
void SLTPushBack(SLTNode** pphead,SLTDateType x);//尾插
void SLTPushiFront(SLTNode** pphead, SLTDateType x);//头插
void SLTPopBack(SLTNode** pphead);//尾删
void SLTPopFront(SLTNode** pphead);//头删
void SLTInsert(SLTNode** pphead,SLTNode* pos,SLTDateType x);//任意位置之前插入
SLTNode* SLTFind(SLTNode** pphead, SLTDateType x);//查找接口
void SLTInsertAfter(SLTNode* pos, SLTDateType x);//任意位置之后插入
void SLTErase(SLTNode** pphead, SLTNode* pos);//删除pos指向的节点
void SLTEraseAfter(SLTNode* pos);//删除pos指向之后的节点
void SLTDestroy(SLTNode** pphead);//销毁链表接口
//SList.c
#include"SList.h"

SLTNode* SLTBuyNode(SLTDateType x)
{
	//申请一块新的空间
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	//放内容
	newnode->date = x;
	newnode->next = NULL;
	//返回地址
	return newnode;
}

SLTNode* SLTFind(SLTNode** pphead, SLTDateType x)
{
	//检查
	assert(pphead);//别传空指针进来
	//这里可以传空链表吗?可以!顶多找不到给你返回一个NULL嘛

	//遍历链表
	SLTNode* pcur = *pphead;
	while (pcur)//当pcur找到NULL时候就会停止
	{
		if (pcur->date == x)
		{
			return pcur;//满足条件,返回该节点的地址
		}
		pcur = pcur->next;//更新指针
	}
	//如果什么都没有找到的话,是不是会不太合适\
	// 所以我们规定如果没有找到,返回NULL地址

	return NULL;
}

void SLTPrint(SLTNode* phead)
{
	//定义一个新的指针
	SLTNode* pcur = phead;

	//循环打印即可,什么时候停止?pcur不指向空便不停止
	while (pcur)
	{
		//打印数据
		printf("%d->", pcur->date);
		//更新指针
		pcur = pcur->next;
	}

	//为了完善,我给最后也加一个NULL
	printf("NULL\n");
}

void SLTPushBack(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);

	//申请一块新的空间
	SLTNode* newnode = SLTBuyNode(x);
	//分两种情况
	//链表为空
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else//链表不为空
	{
		SLTNode* ptail = *pphead;//用于找到链表的尾节点
		while (ptail->next)
		{
			ptail = ptail->next;
		}//找到尾节点
		ptail->next = newnode;//给他接上
	}
}

void SLTPushiFront(SLTNode** pphead, SLTDateType x)
{
	assert(pphead);

	//申请一块新的空间
	SLTNode* newnode = SLTBuyNode(x);
	//把原来第一个结点的地址交给新节点的next
	newnode->next = *pphead;
	*pphead = newnode;//把头部指针更新一下
}

void SLTPopBack(SLTNode** pphead)
{
	//检验
	assert(pphead);//原本的指针不能是空
	assert(*pphead);//传过来的不能是空指针给我删除啊

	//删除
	//这里分两种情况
	//1.只有一个节点的情况
	if (*pphead == NULL)
	{
		free(*pphead);
		*pphead = NULL;
		return;
	}
	else//多个节点的情况
	{
		//需要找到最后一个节点和倒数第二个节点
		//最后一个节点是为了释放空间
		//倒数第二个节点是为了把他的next部分置为空
		SLTNode* ptail = *pphead;
		SLTNode* prev = *pphead;
		while (ptail->next)
		{
			prev = ptail;
			ptail = ptail->next;
		}

		//第二个节点next置为空
		prev->next = NULL;
		//销毁第一个节点
		free(ptail);
		ptail = NULL;
	}
}

void SLTPopFront(SLTNode** pphead)
{
	//检验
	assert(pphead);//检验你别给我传个空
	assert(*pphead);//检验链表不为空,空链表删除什么?

	//开始准备删除
	SLTNode* next = (*pphead)->next;//记录一下要接上的地址
	free(*pphead);//释放第一个节点
	*pphead = next;
}


void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{
	//检验
	assert(pphead);//传入地址不得为空
	assert(pos);//pos不得为空
	assert(*pphead);//要加上链表不得为空,
	//这是因为pos是链表的一个节点的地址,如 
    //果链表不存在,那么pos也会不存在

	//这里要分情况进行处理
	//1.pos刚好是头节点
	if (pos == *pphead)
	{
		//直接调用头插
		SLTPushiFront(pphead,x);
		return;
	}
	else//2.如果pos不是头节点
	{
		SLTNode* prev = *pphead;
		//让prev找到pos之前的节点的地址
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		
		SLTNode* newnode = SLTBuyNode(x);//申请空间
		prev->next = newnode;//把新空间链接到我们前一个节点
		newnode->next = pos;//把新空间与pos指向的空间链接在一起
	}
}


void SLTInsertAfter(SLTNode* pos, SLTDateType x)//之后
{
	//检查
	assert(pos);
	
	//申请空间
	SLTNode* newnode = SLTBuyNode(x);

	//关联新节点的错误写法,原因:pos值的改变
	//pos->next = newnode;
	//newnode->next = pos->next;

	//关联新节点的正确写法:
	//先接后面,再接前面
	newnode->next = pos->next;
	pos->next = newnode;

}

void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	//检查
	assert(pphead);//不得传空
	assert(*pphead);//不得为空链表
	assert(pos);

	//pos刚好是头节点的情况,头删
	if (*pphead == pos)
	{
		//头删
		SLTPopFront(pphead);
		return;
	}
	//如果不是头节点
	else {
		//找到pos之前的节点
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}

}


void SLTEraseAfter(SLTNode* pos)
{
	//检查
	assert(pos);//传过来的地址不可以为空
	assert(pos->next);//传过来的地址的下一个地址不得为空

	SLTNode* del = pos->next;//记录要删除的节点的地址
	pos->next = pos->next->next;//更新pos中next的地址
	free(del);//释放空间
	del = NULL;//临时指针及时置为空
}

void SLTDestroy(SLTNode** pphead)
{
	assert(pphead);//传过来的指针不得为空
	assert(*pphead);//链表不得为空,空链表不用销毁

	//创建遍历指针
	SLTNode* pcur = *pphead;
	//循环销毁
	while (pcur)//啥时候停止?pcur指向NULL
	{
		SLTNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	//最后把头指针也置为NULL
	*pphead = NULL;
}
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"

void test1()
{
	//头指针
	SLTNode* phead = NULL;
	//造一点结点
	SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
	node1->date = 1;
	SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
	node2->date = 2;
	SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
	node3->date = 3;
	SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
	node4->date = 4;
	SLTNode* node5 = (SLTNode*)malloc(sizeof(SLTNode));
	node5->date = 5;

	//链接这些节点
	phead = node1;
	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = node5;
	node5->next = NULL;

	//调用一下打印函数
	SLTPrint(phead);
}

void test2()
{
	SLTNode* phead = NULL;

	SLTPushBack(&phead,6);
	SLTPrint(phead);

	SLTPushiFront(&phead,0);
	SLTPushiFront(&phead,1);
	SLTPushiFront(&phead,2);
	SLTPushiFront(&phead,3);
	SLTPushiFront(&phead,4);
	SLTPushiFront(&phead,5);
	SLTPrint(phead);//5->4->3->2->1->0->6->NULL

	SLTPopBack(&phead);
	SLTPrint(phead);//5->4->3->2->1->0->NULL
	SLTPopFront(&phead);
	SLTPopFront(&phead);
	SLTPopFront(&phead);
	SLTPopFront(&phead);
	SLTPrint(phead);//1->0->NULL
	
	SLTNode* find = SLTFind(&phead,1);
	SLTInsert(&phead, find, 2);
	SLTPrint(phead);//2->1->0->NULL
	SLTInsertAfter(find, 8);
	SLTPrint(phead);//2->1->8->0->NULL
	
	SLTEraseAfter(find);
	SLTPrint(phead);//2->8->0->NULL

	SLTDestroy(&phead);
	SLTPrint(phead);//NULL

}

int main()
{
	//测试我的打印函数
	//test1();
	//测试我的插入与删除函数
	test2();
	return 0;
}

完。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第三十六天|435. 无重叠区间 763.划分字母区间 56. 合并区间

435. 无重叠区间 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 细节&#xff1a; 1. 这道题目和 452.用最少数量的箭引爆气球 &#xff0c;452中的弓箭数量其实就是 无重叠区间的数量&#xff0c;用总的区间数减去 无重叠区间的数…

C++入门学习(二十九)goto语句

在C中&#xff0c;goto语句是一种控制流语句&#xff0c;用于无条件地转移到程序中指定的行。goto语句的使用通常是不推荐的&#xff0c;因为它可能导致代码结构变得混乱、不易理解和维护。然而&#xff0c;在某些特殊情况下&#xff0c;goto语句可能是一种有效的解决方法。 示…

day2 2/19

1> 使用fread和fwrite完成两个文件的拷贝 #include<myhead.h> int main(int argc, const char *argv[]) {FILE*fp1NULL;FILE*fp2NULL;if((fp1fopen("./ggb.bmp","r"))NULL){perror("fopen error");return -1;}if((fp2fopen("./bl…

为什么你用的redis没有出现雪崩,击穿,穿透

一、前言 在大规模并发访问系统中&#xff0c;如果你的系统用到redis&#xff0c;在面试的时候面试官往往会问你的系统有没有出现雪崩&#xff0c;击穿&#xff0c;穿透这样的场景&#xff0c;然后是怎样解决的。博主也经常反复温习redis的特性&#xff0c;总是被雪崩&#xf…

MySQL数据库基础(十):DQL数据查询语言

文章目录 DQL数据查询语言 一、数据集准备 二、select查询 三、简单查询 四、条件查询 1、比较查询 2、范围查询 3、逻辑查询 4、模糊查询 5、非空查询 五、排序查询 六、聚合查询 七、分组查询与having子句 1、分组查询介绍 2、group by的使用 3、group by 聚…

Linux超详细笔记

文章目录 Linux学习笔记操作系统Linux初识Linux的诞生Linux内核Linux发行版 虚拟机VMware安装远程连接Linux系统FinalShellFinalShell连接Linux WSL配置UbuntuLinux常用命令1.入门2.ls命令cd命令3.pwd命令4.相对路径和绝对路径5.mkdir命令6.文件操作命令&#xff08;1&#xff…

初始HTTP协议

一、http协议 1、http相关概念 互联网&#xff1a;是网络的网络&#xff0c;是所有类型网络的母集因特网&#xff1a;世界上最大的互联网网络。即因特网概念从属于互联网概念。习惯上&#xff0c;大家把连接在因特网上的计算机都成为主机。万维网&#xff1a;WWW&#xff08;…

NodeLocal DNS介绍及部署应用

1 NodeLocal DNS是什么&#xff1f; NodeLocal DNSCache 通过在集群节点上运行一个 DaemonSet 来提高 clusterDNS 性能和可靠性。处于 ClusterFirst 的 DNS 模式下的 Pod 可以连接到 kube-dns 的 serviceIP 进行 DNS 查询。通过 kube-proxy 组件添加的 iptables 规则将其转换为…

函数模板与模板的特例化

函数模板 模板的意义&#xff1a;对类型进行参数化 模板类型参数 c使用class、typename关键字定义模板类型参数 函数模板&#xff1a;不进行编译&#xff0c;因为类型还不知道 template <typename T>//定义一个模板参数列表 bool compare(T a,T b)//compare是一个函…

通用二进制方式安装MySQL8.0.x

一、必要说明 1、系统&#xff1a;openEuler操作系统 2、版本&#xff1a;MySQL - 8.0.36 3、下载地址&#xff1a;https://dev.mysql.com/get/Downloads/MySQL-8.0 二、安装步骤 1、下载glibc版本的Mysql [rootnode2 ~]# wget -c https://dev.mysql.com/get/Downloads/MySQ…

C++ bfs反向建图(六十)【第七篇】

今天我们来学习一下bfs反向建图 1.bfs的反向建图 我们之前在图上求最短路都是求从起点出发到每个点的最短路&#xff0c;不过有时候我们也会遇到让求每个点到终点的最短路的问题&#xff0c;此时我们可以怎么做呢&#xff1f; 如果从每个点出发&#xff0c;用 BFS 搜索到终点…

测试开发【Mock平台】13基础:拦截器服务实现(四) 简单规则匹配逻辑

【Mock平台】为系列测试开发教程&#xff0c;从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台&#xff0c;希望作为一个实战项目对各位的测试开发学习之路有帮助&#xff0c;关注公众号发送“mock”获取github项目源码地址&#xff0c;大奇一个…

RocketMQ—RocketMQ消息重复消费问题

RocketMQ—RocketMQ消息重复消费问题 重复消费问题的描述 什么情况下会发生重复消费的问题&#xff1a; 生产者多次投递消息&#xff1a;如果生产者发送消息时&#xff0c;连接有延迟&#xff0c;MQ还没收到消息&#xff0c;生产者又发送了一次消息&#xff1b; 消费者方扩容…

【漏洞复现-通达OA】通达OA WHERE_STR 存在前台SQL注入漏洞

一、漏洞简介 通达OA(Office Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化软件,是与中国企业管理实践相结合形成的综合管理办公平台。通达OA WHERE_STR存在前台SQL注入漏洞,攻击者可通过该漏洞获取数据库敏感信息。 二、影响版本 ●…

将其它输入法的词库转换为微软拼音输入法的自学习词库

上班第一天&#xff0c;我删除了搜狗输入法 曾几何时&#xff0c;搜狗拼音输入法&#xff0c;以丰富的词库&#xff0c;实用的设置成为我电脑端主要的中文输入法。但新年上班的第一天&#xff0c;我彻底删除了它&#xff0c;回归到微软拼音输入法。因为&#xff0c;最近&#…

同学在外包干了两年的点点点,24岁人就快废了

前言 简单的说下&#xff0c;我大学的一个同学&#xff0c;毕业后我自己去了自研的公司&#xff0c;他去了外包&#xff0c;快两年了我薪资、技术各个方面都有了很大的提升&#xff0c;他在外包干的这两年人都要废了&#xff0c;技术没一点提升&#xff0c;学不到任何东西&…

辽宁博学优晨教育科技有限公司视频剪辑培训靠谱吗?

在数字媒体日益繁荣的今天&#xff0c;视频剪辑已成为一项炙手可热的技能。不少培训机构纷纷涉足这一领域&#xff0c;辽宁博学优晨教育科技有限公司便是其中之一。然而&#xff0c;面对众多的选择&#xff0c;很多人不禁要问&#xff1a;辽宁博学优晨教育科技有限公司的视频剪…

中国传媒网CEO徐晓艺:媒体融合发展业态新媒体年后在沪召开

近日,在“坚守媒体初心,拥抱AI时代”2023外滩新媒体年会上,有多项合作达成。 在当前竞争激烈的市场环境中,媒体宣传已经成为企业品牌推广不可或缺的一环。对于很多企业来说往往会犯一个错误,就是默默地参加了展会,并没有进行媒体营销。展会是一种非常有力的宣传和推广方式,可以…

网络安全综合实验

1.实验拓扑 在这里注意因为第四个要求配置双击热备&#xff0c;我们可以第一时间配置&#xff0c;避免二次重复配置消耗时间 4、FW1和FW3组成主备模式的双机热备 具体配置位置在系统-->高可靠性-->双机热备-->配置 这里上行链路有两组&#xff0c;分别为电信和移动&…

RK356x U-Boot研究所(驱动篇)4.2.2 DRM代码结构分析

谈到 drm 就涉及到 libdrm 库,它是一个跨驱动的中间件,它允许用户空间应用(例如作为Mesa和2D驱动程序)通过DRI与内核通信协议。 如下DRM结构图: libdrm 是DRM下沟通驱动和用户层的库。过去APP可能是使用open(framebuff)这样的方式来和图形驱动沟通,但是在现在的硬件演化…
最新文章