顺序表功能实现(入手版详解)

news2024/12/26 14:42:25

🍉博客主页:阿博历练记
📖文章专栏:数据结构与算法
🚚代码仓库:阿博编程日记
🌹欢迎关注:欢迎友友们点赞收藏+关注哦

在这里插入图片描述

文章目录

    • 🍓前言
    • ✨顺序表
      • 🔍1.顺序表的整体框架
      • 🔍2.打印顺序表的菜单
      • 🔍3.主函数的创建
      • ⭐第一个case后面加中括号
      • ⭐枚举变量和函数名同名
      • 🔍4.顺序表的定义
      • 🔍5.顺序表的初始化
      • ⭐传结构体本身还是它的地址
      • 🔍6.顺序表的尾插
      • 🔍7.顺序表的打印
      • 🔍8.顺序表的头插
      • ⭐挪动数据(从后往前)
      • 🔍9.顺序表的尾删
      • ⭐assert的声明
      • ⭐数组越界不一定报错
      • 🔍10.顺序表的头删
      • ⭐挪动数据(从前往后)
      • 🔍11.顺序表任意位置的插入
      • 🔍12.顺序表任意位置的删除
      • ⭐assert声明的改变&&函数的附用
      • 🔍13.顺序表数据的查找
      • 🔍13.顺序表数据的修改
      • 🔍14.顺序表的销毁
      • 👻Seqlist.h代码
      • 👻Seqlist.c代码
      • 👻test.c代码

🍓前言

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
1.静态顺序表:使用定长数组存储元素.
2.动态顺序表:使用动态开辟的数组存储.
在这里插入图片描述
友友们,这里虽然顺序表删除需要挪动大量的元素很不方便,但是顺序表有个绝对的优势就是下标的随机访问,比如:二分查找、还有一些排序都需要作用到数组之上.

✨顺序表

🔍1.顺序表的整体框架

1.创建一个test.c文件:测试顺序表的相关功能
2.创建一个SeqList.c文件:实现顺序表功能的定义
3.创建一个SeqList.h文件:实现顺序表功能的声明

🔍2.打印顺序表的菜单

void  menu()
{
	printf("***************************\n");
	printf("****1.尾插数据 2.尾删数据****\n");
	printf("****3.头插数据 4.头删数据****\n");
	printf("****5.打印数据 0.退出   ****\n");
	printf("***************************\n");
}

🔍3.主函数的创建

enum option
{ 
	Destory,
	PushBack,
	PopBack,
	PushFront,
	PopFront,
	Print,
};
int  main()
{
	SL  s;
	SLInit(&s);
	int  option = 0;
	do
	{
		menu();
		printf("请输入你的选择:\n");
		scanf("%d", &option);
		switch (option)
		{
		case PushBack:
		{
			printf("请输入要尾插数据的个数,再依次输入要插入的数据:\n");
			int n = 0;
			scanf("%d", &n);
			int x = 0;
			while (n > 0)
			{
				scanf("%d", &x);
				SLPushBack(&s, x);
				n--;
			}
			break;
		}
		case PopBack:
			printf("尾删成功\n");
			SLPopBack(&s);
			break;
		case PushFront:
			printf("请输入要头插数据的个数,在依次输入要插入的数据:\n");
			int n = 0;
			scanf("%d", &n);
			int x = 0;
			while (n > 0)
			{
				scanf("%d", &x);
				SLPushFront(&s, x);
				n--;
			}
			break;
		case PopFront:
			printf("头删成功\n");
			SLPopFront(&s);
			break;
		case Print:
			SLPrint(&s);
			break;
		case Destory:
			SLDestory(&s);
			break;
		default:
			printf("选择错误,请重新选择:\n");
			break;
		}
	} while (option);
	return  0;
}

⭐第一个case后面加中括号

友友们,这里我们加中括号是因为我们需要把它里面的n和x变成局部变量,防止和下面的x和n出现变量的重定义

⭐枚举变量和函数名同名

函数名代表函数的地址,可以认为是函数指针类型,如果我们用它当作枚举变量的话,这里我们就会改变它的类型,当再次调用函数的时候,程序就会报错.

在这里插入图片描述

🔍4.顺序表的定义

//typedef int SLDatatype;
//
//struct Seqlist
//{
//	SLDatatype  a[N];     //静态的顺序表 给小了不够用,给大了浪费,这里我们考虑动态顺序表
//	int size;          
//};

typedef int SLDatatype;

typedef struct Seqlist
{
	SLDatatype * a;     //动态的顺序表
	int size;       //存储的有效数据个数
	int  capcity;    //容量空间
}SL;

🔍5.顺序表的初始化

void  SLInit(SL* ps1)
{
	assert(ps1);
	ps1->a =(SLDatatype*)malloc(sizeof(SLDatatype)*4);
	if (ps1->a == NULL)
	{
		perror("malloc");
		return;
	}
	ps1->capcity = 4;
	ps1->size = 0;
}

⭐传结构体本身还是它的地址

1.传结构体本身
在这里插入图片描述
2.传结构体的地址
在这里插入图片描述

友友们,这里传结构体本身,形参相当于实参的一份临时拷贝,形参的改变不会影响实参,所以如果如果我们要改变它,就要传它的地址,这样我们解引用就可以改变它了.

🔍6.顺序表的尾插

 void  SLCheckcapcity(SL*ps1)
{
	assert(ps1);
	if (ps1->size == ps1->capcity)
	{
		SLDatatype* temp =(SLDatatype*) realloc(ps1->a, sizeof(SLDatatype) * ps1->capcity * 2);		
		if (temp == NULL)
		{
			perror("realloc");
			return;
		}
		ps1->a = temp;
		ps1->capcity *= 2;
	}
}
void  SLPushBack(SL* ps1, SLDatatype x)
{
	assert(ps1);
	SLCheckcapcity(ps1);
	ps1->a[ps1->size++] = x;
}

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

🔍7.顺序表的打印

void  SLPrint(SL* ps1)
{
	assert(ps1);
	for (int i = 0; i < ps1->size; i++)
	{
		printf("%d ", ps1->a[i]);
	}
	printf("\n");
}

🔍8.顺序表的头插

1.方法一:

void  SLPushFront(SL* ps1, SLDatatype x)
{
	assert(ps1);
	SLCheckcapcity(ps1);
	//挪动数据
	int  end = ps1->size - 1;
	while (end >= 0)
	{
		ps1->a[end + 1] = ps1->a[end];
		end--;
	}
	ps1->a[0] = x;
	ps1->size++;
}

⭐挪动数据(从后往前)

在这里插入图片描述
2.方法二:

void  SLPushFront(SL* ps1, SLDatatype x)
{
	assert(ps1);
	SLCheckcapcity(ps1);
	//挪动数据
	int  end = ps1->size;
	while (end > 0)
	{
		ps1->a[end] = ps1->a[end-1];
		end--;
	}
	ps1->a[0] = x;
	ps1->size++;
}

🔍9.顺序表的尾删

void  SLPopBack(SL* ps1)
{
	assert(ps1->size > 0&&ps1);   //暴力检查
	ps1->size--;
}

在这里插入图片描述

⭐assert的声明

友友们注意,如果我们顺序表里面有5个数据,而我们尾删6次,这时候ps1->size就变成-1了,就会出现数组越界,就是第一个数据放到下标为-1的位置上了,导致结果出错. 所以这里我们就需要assert来声明一下:如果顺序表为空,就不需要再尾删了.

在这里插入图片描述

⭐数组越界不一定报错

友友们一定要清楚越界本身就是一个抽查,并不是一定会报错的,如果数组下标越界了,那么它会自动接着那块内存往后写,如果界外的空间暂时没有被利用,那么我们就可以占用那块内存,但是如果界外的内存已经存放了数据,我们越界过去就会覆盖那块内存,则就有可能导致错误的产生.

🔍10.顺序表的头删

1.方法一:start为1

void  SLPopFront(SL* ps1)
{
	assert(ps1);
	assert(ps1->size > 0);
	int  start = 1;
	while (start < ps1->size)
	{
		ps1->a[start - 1] = ps1->a[start];
		start++;
	}
	ps1->size--;
}

2.方法二:start为0

void  SLPopFront(SL* ps1)
{
	assert(ps1);
	assert(ps1->size > 0);
	int  start = 0;
	while (start < ps1->size-1)
	{
		ps1->a[start] = ps1->a[start+1];
		start++;
	}
	ps1->size--;
}

⭐挪动数据(从前往后)

在这里插入图片描述

🔍11.顺序表任意位置的插入

void  SLInsert(SL* ps1, int pos,SLDatatype x)
{
	assert(pos >= 0 && pos <= ps1->size&&ps1);    //防止越界访问
	SLCheckcapcity(ps1);
	int end = ps1->size - 1;
	while (end >= pos)
	{
		ps1->a[end + 1] = ps1->a[end];
		end--;
	}
	ps1->a[pos] = x;
	ps1->size++;
}

在这里插入图片描述

友友们,这里我们的头插尾插其实就是两种特殊位置的任意插入,这时候我们就可以附用这个函数,比如头插:SLInsert(ps1,0,x),尾插:SLInsert(ps1,ps1->size,x).

🔍12.顺序表任意位置的删除

1.方法一:start为pos+1

void  SLErase(SL* ps1, int pos)
{
	assert(pos >= 0 && pos < ps1->size&&ps1);   //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素
	int  start = pos + 1;
	while (start < ps1->size)
	{
		ps1->a[start - 1] = ps1->a[start];
		start++;
	}
	ps1->size--;
}

2.方法二:start为pos

void  SLErase(SL* ps1, int pos)
{
	assert(pos >= 0 && pos < ps1->size&&ps1);   //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素
	int  start = pos;
	while (start < ps1->size-1)
	{
		ps1->a[start] = ps1->a[start+1];
		start++;
	}
	ps1->size--;
}

⭐assert声明的改变&&函数的附用

友友们注意,这里pos就不能等于ps1->size了,因为我们要删除顺序表中的数据,它最多下标为ps1->size-1.这里我们的头删尾删就可以附用这个函数,头删就是:SLErase(ps1,0),尾删就是:(ps1,ps1->size-1).

🔍13.顺序表数据的查找

int   SLFind(SL* ps1, SLDatatype x)
{
	assert(ps1);
	for (int i = 0; i < ps1->size; i++)
	{
		if (ps1->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

友友们注意,因为下标不可能是负数,所以我们没有找到就可以返回负数,一般我们都使用-1.

🔍13.顺序表数据的修改

void  Modify(SL* ps1, int pos, SLDatatype x)
{
	assert(pos >= 0 && pos < ps1->size&&ps1);
	ps1->a[pos] = x;
}

🔍14.顺序表的销毁

1.free之后需要置空

void  SLDestory(SL*ps1)
{
	assert(ps1);
	free(ps1->a);
	ps1->a = NULL;
	ps1->size = 0;
	ps1->capcity = 0;
}

友友们,这里我们把ps1->a释放之后,因为它不是在函数内部创建的指针变量,它存放的是顺序表的地址,所以释放之后,函数外部可能会调用到它,所以我们这里需要及时置空.

2.free之后不需要置空

void rate(int* nums, int numsSize, int k)
{
	if (k > numsSize)
	{
		k %= numsSize;
	}
	int* temp = (int*)malloc(sizeof(int) * numsSize);
	memcpy(temp + k, nums, sizeof(int) * numsSize - k);
	memcpy(temp, nums + numsSize - k, sizeof(int) * k);
	memcpy(nums, temp, sizeof(int) * numsSize);
	free(temp);
	temp = NULL;
}

友友们注意了,这里的temp是我们在这个函数内部创建的指针变量,它是一个局部变量,它出完函数作用域就销毁了,所以我们free释放之后,就还给操作系统了,以后它也不会被调用了,所以这里我们不置空也是可以的.

👻Seqlist.h代码

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//typedef int SLDatatype;
//
//struct Seqlist
//{
//	SLDatatype  a[N];     //静态的顺序表 给小了不够用,给大了浪费,这里我们考虑动态顺序表
//	int size;          
//};

typedef int SLDatatype;

typedef struct Seqlist
{
	SLDatatype * a;     //动态的顺序表
	int size;       //存储的有效数据个数
	int  capcity;    //容量空间
}SL;
void  SLInit(SL* ps1);
void  SLDestory(SL *ps1);
void  SLPushBack(SL* ps1, SLDatatype x);
void  SLPushFront(SL* ps1, SLDatatype x);
void  SLPopBack(SL* ps1);
void  SLPopFront(SL* ps1);
void  SLPrint(SL* ps1);
void  SLInsert(SL* ps1, int pos,SLDatatype x);
void  SLErase(SL* ps1, int pos);
//找到了返回下标,找不到返回-1
int   SLFind(SL* ps1, SLDatatype x);
void  Modify(SL* ps1, int pos, SLDatatype x);

👻Seqlist.c代码

#define  _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void  SLInit(SL* ps1)
{
	assert(ps1);
	ps1->a =(SLDatatype*)malloc(sizeof(SLDatatype)*4);
	if (ps1->a == NULL)
	{
		perror("malloc");
		return;
	}
	ps1->capcity = 4;
	ps1->size = 0;
}
void  SLDestory(SL*ps1)
{
	assert(ps1);
	free(ps1->a);
	ps1->a = NULL;
	ps1->size = 0;
	ps1->capcity = 0;
}
void  SLPrint(SL* ps1)
{
	assert(ps1);
	for (int i = 0; i < ps1->size; i++)
	{
		printf("%d ", ps1->a[i]);
	}
	printf("\n");
}
void  SLCheckcapcity(SL*ps1)
{
	assert(ps1);
	if (ps1->size == ps1->capcity)
	{
		SLDatatype* temp =(SLDatatype*) realloc(ps1->a, sizeof(SLDatatype) * ps1->capcity * 2);		
		if (temp == NULL)
		{
			perror("realloc");
			return;
		}
		ps1->a = temp;
		ps1->capcity *= 2;
	}
}
void  SLPushBack(SL* ps1, SLDatatype x)
{
	assert(ps1);
	SLCheckcapcity(ps1);
	ps1->a[ps1->size++] = x;
}
void  SLPushFront(SL* ps1, SLDatatype x)
{
	assert(ps1);
	SLCheckcapcity(ps1);
	//挪动数据
	int  end = ps1->size;
	while (end >0)
	{
		ps1->a[end] = ps1->a[end-1];
		end--;
	}
	ps1->a[0] = x;
	ps1->size++;
	/*assert(ps1);
	SLInsert(ps1, 0, x);*/
}
void  SLPopBack(SL* ps1)
{
	assert(ps1->size > 0&&ps1);   //暴力检查
	/*ps1->a[ps1->size - 1] = 0;*/  //有可能最后一个数据就是0
	/*if (ps1->size == 0) 
	{
		return;
	}*/
	ps1->size--;
	/*assert(ps1);
	SLErase(ps1, ps1->size - 1);*/
}
void  SLPopFront(SL* ps1)
{
	assert(ps1);
	assert(ps1->size > 0);
	int  start = 0;
	while (start < ps1->size-1)
	{
		ps1->a[start] = ps1->a[start+1];
		start++;
	}
	ps1->size--;
}
void  SLInsert(SL* ps1, int pos,SLDatatype x)
{
	assert(pos >= 0 && pos <= ps1->size&&ps1);    //防止越界访问
	SLCheckcapcity(ps1);
	int end = ps1->size - 1;
	while (end >= pos)
	{
		ps1->a[end + 1] = ps1->a[end];
		end--;
	}
	ps1->a[pos] = x;
	ps1->size++;
}
void  SLErase(SL* ps1, int pos)
{
	assert(pos >= 0 && pos < ps1->size&&ps1);   //注意这里不能等于ps1->size,因为这里是删除,它本身就没有那么多的元素
	int  start = pos;
	while (start < ps1->size-1)
	{
		ps1->a[start] = ps1->a[start+1];
		start++;
	}
	ps1->size--;
}
int   SLFind(SL* ps1, SLDatatype x)
{
	assert(ps1);
	for (int i = 0; i < ps1->size; i++)
	{
		if (ps1->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}
void  Modify(SL* ps1, int pos, SLDatatype x)
{
	assert(pos >= 0 && pos < ps1->size&&ps1);
	ps1->a[pos] = x;
}

👻test.c代码

#define  _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void  menu()
{
	printf("***************************\n");
	printf("****1.尾插数据 2.尾删数据****\n");
	printf("****3.头插数据 4.头删数据****\n");
	printf("****5.打印数据 0.退出   ****\n");
	printf("***************************\n");
}
enum option
{ 
	Destory,
    PushBack,
	PopBack,
	PushFront,
	PopFront,
	Print,
};
int  main()
{
	SL  s;
	SLInit(&s);
	int  option = 0;
	do
	{
		menu();
		printf("请输入你的选择:\n");
		scanf("%d", &option);
		switch (option)
		{
		case PushBack:
		{
			printf("请输入要尾插数据的个数,再依次输入要插入的数据:\n");
			int n = 0;
			scanf("%d", &n);
			int x = 0;
			while (n > 0)
			{
				scanf("%d", &x);
				SLPushBack(&s, x);
				n--;
			}
			break;
		}
		case PopBack:
			printf("尾删成功\n");
			SLPopBack(&s);
			break;
		case PushFront:
			printf("请输入要头插数据的个数,在依次输入要插入的数据:\n");
			int n = 0;
			scanf("%d", &n);
			int x = 0;
			while (n > 0)
			{
				scanf("%d", &x);
				SLPushFront(&s, x);
				n--;
			}
			break;
		case PopFront:
			printf("头删成功\n");
			SLPopFront(&s);
			break;
		case Print:
			SLPrint(&s);
			break;
		case Destory:
			SLDestory(&s);
			break;
		default:
			printf("选择错误,请重新选择:\n");
			break;
		}
	} while (option);
	return  0;
}

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

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

相关文章

【SpringBoot】SpringBoot 优雅地校验参数

1、为什么要校验参数&#xff1f; 在日常的开发中&#xff0c;为了防止非法参数对业务造成影响&#xff0c;需要对接口的参数进行校验&#xff0c;以便正确性地入库。 例如&#xff1a;登录时&#xff0c;就需要判断用户名、密码等信息是否为空。虽然前端也有校验&#xff0c;…

剑指offer 栈习题训练经验总结(未完)

第一题 定义栈的数据结构&#xff0c;请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中&#xff0c;调用 min、push 及 pop 的时间复杂度都是 O(1)。 class MinStack {private:stack<int> s;stack<int> min_s;public:void push(int x) {s.push(x);if…

xxl-job 集成 SpringBoot 使用

文章目录 前言xxl-job 集成 SpringBoot 使用1. xxl-job 安装部署超链接2. 启动xxl-job3. 集成 SpringBoot 使用3.1. 添加依赖3.2. 执行器 配置3.3. 执行器组件配置3.4. XxlJob 开发步骤 4. &#xff08;BEAN模式&#xff09;示例5. GLUE(Java) 示例6. 注意 前言 如果您觉得有用…

视觉震撼的数据可视化示例

众所周知&#xff0c;数据可以非常强大——当你真正理解它告诉你什么时。 数据和信息可视化(数据可视化或信息可视化)是对大量复杂的定量、定性数据、信息进行设计和创建易于沟通、易于理解的图形或视觉表示的实践&#xff0c;在静态、动态或交互式视觉项目的帮助下&#xff0…

Java对象的创建方式以及对象的引用

日子就是这么的庸常&#xff0c;却有细碎的事物&#xff0c;如太阳碎碎的光芒&#xff0c;洒落其上 Java创建对象有几种方式 new创建新对象 new创建我们就很熟悉了&#xff0c;像Person p new Person();等等 通过反射机制 这种创建对象的方式就是当我们编译时不知道要创…

java面试,redis面试,java面试大全

LEARNING_CONTENT 一个分布式锁的解决方案&#xff0c;另一个是分布式事务的解决方案 -2 flink 链接&#xff1a;flink参考文章 -1 linux of view 参考链接&#xff1a; linux常见面试题 linux查看占用cup最高的10个进程的命令&#xff1b; 参考文章&#xff1a;linux查看…

uboot 启动内核代码分析

0、uboot和内核区别 uboot的本质就是一个复杂点的裸机程序。内核本身也是一个"裸机程序“&#xff0c;和uboot、和其他裸机程序并没有本质区别。 区别就是操作系统运行起来后在软件上分为内核层和应用层&#xff0c;分层后两层的权限不同&#xff0c;在内存访问和设备操作…

iptables 防火墙进出控制

iptables 防火墙进出控制 iptables简介 iptables 是集成在 Linux 内核中的包过滤防火墙系统。使用 iptables 可以添加、删除具体的过滤规则&#xff0c;iptables 默认维护着 4 个表和 5 个链&#xff0c;所有的防火墙策略规则都被分别写入这些表与链中。 “四表”是指 iptab…

ES是如何解决高可用

https://www.cnblogs.com/crazymakercircle/p/15433680.html ES是一个分布式全文检索框架&#xff0c;隐藏了复杂的处理机制&#xff0c;核心数据分片机制、集群发现、分片负载均衡请求路由。 ES的高可用架构&#xff0c;总体如下图&#xff1a; 说明&#xff1a;本文会以pdf…

SQL 招聘网站岗位数据分析

数据清洗 1.删除包含空字段的行 create view v_data_clean_null as select * from data d where job_href is not null and job_href ! and job_name is not null and job_name ! and company_href is not null and company_href ! and company_name is not null and com…

OpenAI ChatGPT Unity接入

OpenAI ChatGPT Unity接入 OpenAI ChatGPT Unity接入OpenAi-API-Unity 方法OpenAi-API-Unity 下载本地配置Unity 模块URL接入gz 接入json 接入Open AIOpenAi-Api-Unity 插件文档 OpenAi 本地化接入 Unity 方法Unity 关键字识别语音合成 & 文字转语音音频记录 & 实时音频…

基于物联网及云计算技术的智慧充电桩平台设计方案

针对目前的充电桩监管难题&#xff0c;如何逐一击破各个痛点&#xff1f; TSINGSEE可提供基于"智能充电设备&#xff0b;云平台&#xff0b;APP小程序"一体化完整的解决方案&#xff0c;解决当前充电桩运营商面临的各种运营和管理难题。 一、方案介绍 方案充分利用…

容器技术的发展

容器技术的发展 近年来&#xff0c;随着计算机硬件、网络以及云计算等技术的迅速发展&#xff0c;云原生的概念也越来越受到业界人士的广泛关注&#xff0c;越来越多的应用场景开始拥抱云原生&#xff0c;其中容器技术的发展起着至关重要的作用。本章将介绍容器技术的基础知识…

瘦身必备!四款低卡美食狂掉20斤肥肉

夏天来了&#xff0c;想要减肥瘦身&#xff0c;却总是被高卡路里的食物所困扰&#xff1f;别担心&#xff0c;今天我为大家介绍四款低卡掉秤减脂美食&#xff0c;让你轻松享受美食的同时还能达到减肥的目的。 这四款美食简单易做&#xff0c;口感也十分好吃&#xff0c;适合各…

《花雕学AI》ChatGPT 的 Prompt 用法,不是随便写就行的,这 13 种才是最有效的

ChatGPT 是一款基于 GPT-3 模型的人工智能写作工具&#xff0c;它可以根据用户的输入和要求&#xff0c;生成各种类型和风格的文本内容&#xff0c;比如文章、故事、诗歌、对话、摘要等。ChatGPT 的强大之处在于它可以灵活地适应不同的写作场景和目的&#xff0c;只要用户给出合…

【STM32】定时器PWM模式详解

PWM模式&#xff1a; PWM模式1&#xff0c;向上计数时&#xff0c;PWM信号从有效电平变为无效电平 PWM模式2&#xff0c;向上计数时&#xff0c;PWM信号从无效电平变为有效电平 PWM极性&#xff1a; 极性为高时&#xff0c;高电平为有效电平&#xff0c;低电平为无效电平 极性…

【Android取证篇】Android设备USB调试打开方式(开发者模式)

【Android取证篇】Android设备USB调试打开方式(开发者模式) Android各个版本系统手机开启”USB调试”的入口不全相同&#xff0c;仅供参考—【蘇小沐】 1、【Android1.0-3.2】 路径&#xff1a;在应用列表选择「设置」->「应用程序」->「开发」->勾选「USB调试」选…

拿来吧你——一个类帮你搞定SpringBoot中的请求日志打印

拿来吧你——一个类帮你搞定SpringBoot中的请求日志打印 日常开发工作中避免不了要打印请求日志&#xff0c;这个功能几乎在所有的项目中都需要编写一次&#xff0c;重复的次数多了&#xff0c;难免会感觉繁琐&#xff0c;因此打算搞一个通用类把这块功能拆出来。 废话不多说—…

虹科方案|使用 HK-TRUENAS支持媒体和娱乐工作流程-1

一、摘要 开发和交付能够随时随地触及受众的媒体内容变得越来越重要和复杂。 在当今高度互联、娱乐驱动的世界中&#xff0c;媒体和娱乐 (M&E) 公司需要保持竞争力才能取得成功。 这些组织需要制作各种不同格式的信息和娱乐内容&#xff0c;以便在移动设备、台式机、工作站…

MySQL---基本操作DDL(SQL特点,数据类型,对数据库的操作,对表的操作)

1. SQL的特点 具有综合统一性&#xff0c;不同数据库的支持的SQL稍有不同 非过程化语言 语言简捷&#xff0c;用户容易接受 以一种语法结构提供两种使用方式 2. 对数据库的常用操作 功能 SQL 查看所有的数据库 show databases&#xff1b; 创建数据库 create databa…