顺序表——C语言实现
目录
一、线性表
二、顺序表
1.实现动态顺序表
SeqList.h
SeqList.c
Test.c
问题
经验:free 出问题,2种可能性
解决问题
(2)尾删
(3)头插,头删
(4)在 pos 位插
(5)在 pos 位删
(6)查找
2.整体代码
SeqList.h
SeqList.c
test.c
一、线性表
线性表(linear list)是 n 个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串。
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
二、顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
分类:
(1)静态顺序表:使用定长数组存储元素
(2)动态顺序表:使用动态开辟的数组存储
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小
1.实现动态顺序表
SeqList.h
typedef int SLDataType;
#define INIT_CAPACITY 4 // 初始化容量typedef struct SeqList
{SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量
}SL;// 增删查改
void SLInit(SL* ps);
void SLDestroy(SL* ps);//打印顺序表数据
void SLPrint(SL* ps);void SLPushBack(SL* ps, SLDataType x); // 尾插
void SLPopBack(SL* ps); // 尾删
void SLPushFront(SL* ps, SLDataType x); // 头插
void SLPopFront(SL* ps); // 头删// 扩容,2倍合适
void SLCheckCapacity(SL* ps);
SeqList.c
void SLInit(SL* ps)
{assert(ps);ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);if (ps->a == NULL){perror("malloc fail");return;}ps->size = 0;ps->capacity = INIT_CAPACITY;
}void SLDestroy(SL* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->size = 0; // 结合性,从右往左赋值
}void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; ++i){printf("%d ", ps->a[i]);}printf("\n");
}// 扩容,2倍合适
void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2);//思考这里对不对if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp; // 防止不是原地扩容ps->capacity *= 2;}}void SLPushBack(SL* ps, SLDataType x) // 尾插
{assert(ps);// 扩容 2倍合适SLCheckCapacity(ps);ps->a[ps->size++] = x;
}
Test.c
void TestSeqList1()
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPrint(&s);SLDestroy(&s);
}int main()
{TestSeqList1();return 0;
}
运行上面的代码,顺序表里插入1234:,程序没毛病
问题
void TestSeqList1()
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPushBack(&s, 5);SLPrint(&s);SLDestroy(&s);
}
奇怪的事情发生了:
SLPushBack(&s, 6);
SLPushBack(&s, 7);
奇怪的事情又发生了:
光标在闪
这里反反复复调试都发现不了问题
经验:free 出问题,2种可能性
(1)野指针 或 位置不对。这种情况不多
eg:申请一块空间,从中间位置释放,报错。(应该从起始位置释放)
(2)指针指向的空间(数组)上面,可能有越界。
- 下标越界
- 开少了
解决问题
realloc 返回的是地址,->a,a 我们没有动过,动的都是 a 指向的内容
free 有时候出问题,通常不是free ( ) 里面有问题,而是前面有越界
仔细查,动空间的只有 SLPushBack( )
// 扩容,2倍合适
void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2);//思考这里对不对if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp; // 防止原地扩容ps->capacity *= 2;}}void SLPushBack(SL* ps, SLDataType x) // 尾插
{assert(ps);// 扩容 2倍合适SLCheckCapacity(ps);ps->a[ps->size++] = x;
}
ps->a[ps->size++] = x; 逻辑没有问题,问题大概率出现在扩容
先看下标越界了吗?size 没有越界的可能性
还有一种可能是开少了。
你以为你原来是 4 个,扩容到 8 个。你以为你有 8 个,实际上没有 8 个。你当成 8 个访问的呀,就越了。
8 个 SLDataType 是 4*8=32 字节。
ps->capacity * 2 这里是 4*2=8 字节
正确写法:
// 扩容 2倍合适
void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity *= 2;}
}void SLPushBack(SL* ps, SLDataType x) // 尾插
{assert(ps);SLCheckCapacity(ps);ps->a[ps->size++] = x;
}
问题解决
(2)尾删
void SLPopBack(SL* ps) // 尾删
{assert(ps);//ps->a[ps->size - 1] = 0; 加上没用ps->size--;
}
由 size 遍例顺序表,size -- 后,前 size-1个是有效数据,第 size 个访问不到了
注意:这里不用释放,一部分一部分释放会报错。
但是不用担心,当我们不用这个顺序表时会 SLDestroy(&s) ; 空间还是会释放的
删空了还删,会报错。所以要检查
void SLPopBack(SL* ps) // 尾删
{assert(ps);// 温柔的检查if (ps->size == 0)return;ps->size--;
}
断言 assert 会直接告诉你哪出错了,并且终止掉程序
void SLPopBack(SL* ps) // 尾删
{assert(ps);// 暴力检查assert(ps->size > 0);ps->size--;
}
(3)头插,头删
要挪动数据,以实现顺序表连续性
顺序表尾插,尾删效率不错。头插,头删效率不太行。但有时候就要头插,头删
void SLPushFront(SL* ps, SLDataType x) // 头插
{assert(ps);SLCheckCapacity(ps);//挪动memmove(&(ps->a[1]), &(ps->a[0]), sizeof(SLDataType) * ps->size);//头插ps->a[0] = x;ps->size++;
}void SLPopFront(SL* ps) // 头删
{assert(ps);assert(ps->size > 0);memmove(&(ps->a[0]), &(ps->a[1]), sizeof(SLDataType) * ps->size);ps->size--;
}
我们发现:插入N个数据。尾插时间复杂度:O(N) 头插时间复杂度:O(N^2)
头插1万个数据,要执行1亿次。所以,尽量避免使用头插
疑问:为什么头插用memmove库函数了,时间复杂度还是O(N^2)
答:虽然我们用的是库函数,一步到位,没有用模拟实现。我们分析它的时间复杂度,还是要看到本质,本质就是模拟实现,通过模拟实现分析它的时间复杂度。
本质:
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];--end;}ps->a[0] = x;ps->size++;
}
可以看到,头插1个数据,执行N次,时间复杂度O(N)。头插N个数据,执行N^2次,时间复杂度O(N^2) 从模拟实现的角度看,它是一个等差数列
(4)在 pos 位插
// 顺序表在pos位置插入x
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);// 插入时 = size 相当于尾插SLCheckCapacity(ps);//挪动memmove(&(ps->a[pos + 1]), &(ps->a[pos]), sizeof(SLDataType) * (ps->size - pos));//插入ps->a[pos] = x;ps->size++;
}
我们可以简化头插(在第0位),尾插(在第size位)。
void SLPushBack(SL* ps, SLDataType x) // 尾插
{assert(ps);/*SLCheckCapacity(ps);ps->a[ps->size++] = x;*/SLInsert(ps, ps->size, x);
}void SLPushFront(SL* ps, SLDataType x) // 头插
{assert(ps);/*SLCheckCapacity(ps);//挪动memmove(&(ps->a[1]), &(ps->a[0]), sizeof(SLDataType) * ps->size);//头插ps->a[0] = x;ps->size++;*/SLInsert(ps, 0, x);
}
(5)在 pos 位删
// 顺序表删除pos位置的值
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//覆盖memmove(&(ps->a[pos]), &(ps->a[pos + 1]), sizeof(SLDataType) * (ps->size - pos - 1));ps->size--;
}
可以简化 头删,尾删 的代码。
void SLPopBack(SL* ps) // 尾删
{assert(ps);/*// 暴力检查assert(ps->size > 0);温柔的检查//if (ps->size == 0)// return;ps->size--;*/SLErase(ps, ps->size - 1);
}void SLPopFront(SL* ps) // 头删
{assert(ps);/*assert(ps->size > 0);memmove(&(ps->a[0]), &(ps->a[1]), sizeof(SLDataType) * ps->size);ps->size--;*/SLErase(ps, 0);
}
疑问:用这个新的代码尾删,假设现在size = 8,根据上面代码,最大容量 capacity 也 = 8。要尾删,删下标为7的位置,传给 pos,pos+1 = 8 。SLErase 里面 &(ps->a[pos + 1]) 不会越界访问吗?
解答:这时要 memmove 移动 ps->size - pos - 1 = 0 个字节。我们看 memmove 模拟实现:num 是要移动的字节个数,这里 num = 0 ,循环没进去,也就不存在越界访问了
(6)查找
//顺序表查找
int SLFind(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (x == ps->a[i]){return i;}}return -1;
}
问:为什么删除后,不用 realloc 回收一部分内存的使用权?
答:当扩容时,realloc 开内存,分为异地扩容,本地扩容。想要新开辟空间,如果原空间后面的大小够,就本地扩容,效率高。后面大小不够,就异地扩容,效率低。
而现代计算机内存空间的数量很多,不怕浪费,为保证运行效率,宁愿占着茅坑不拉屎。
当我们确认不再使用时,也会 SLDestroy 释放全部空间
问:为什么不写菜单?
答:数据结构部分,菜单没有什么价值。而且不好调试。菜单一般在命令行程序,控制数据库的服务器,会输入选项(指令去控制)。
写菜单的话,也不要一上来就写菜单。先在 test.c 里写一组一组测试 ,测的没问题了,再写菜单
2.整体代码
SeqList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLDataType;
#define INIT_CAPACITY 4 // 初始化容量typedef struct SeqList
{SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量
}SL;// 增删查改
void SLInit(SL* ps);
void SLDestroy(SL* ps);//打印顺序表数据
void SLPrint(SL* ps);void SLPushBack(SL* ps, SLDataType x); // 尾插
void SLPopBack(SL* ps); // 尾删
void SLPushFront(SL* ps, SLDataType x); // 头插
void SLPopFront(SL* ps); // 头删// 顺序表查找
int SLFind(SL* ps, SLDataType x);
// 顺序表在pos位置插入x
void SLInsert(SL* ps, int pos, SLDataType x);
// 顺序表删除pos位置的值
void SLErase(SL* ps, int pos);// 扩容,2倍合适
void SLCheckCapacity(SL* ps);
SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"void SLInit(SL* ps)
{assert(ps);ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);if (ps->a == NULL){perror("malloc fail");return;}ps->size = 0;ps->capacity = INIT_CAPACITY;
}void SLDestroy(SL* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->size = 0; // 结合性,从右往左赋值
}void SLPrint(SL* ps)
{assert(ps);for (int i = 0; i < ps->size; ++i){printf("%d ", ps->a[i]);}printf("\n");
}// 扩容 2倍合适
void SLCheckCapacity(SL* ps)
{assert(ps);if (ps->size == ps->capacity){SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity *= 2;}
}void SLPushBack(SL* ps, SLDataType x) // 尾插
{assert(ps);/*SLCheckCapacity(ps);ps->a[ps->size++] = x;*/SLInsert(ps, ps->size, x);
}void SLPopBack(SL* ps) // 尾删
{assert(ps);/*// 暴力检查assert(ps->size > 0);温柔的检查//if (ps->size == 0)// return;ps->size--;*/SLErase(ps, ps->size - 1);
}void SLPushFront(SL* ps, SLDataType x) // 头插
{assert(ps);/*SLCheckCapacity(ps);//挪动memmove(&(ps->a[1]), &(ps->a[0]), sizeof(SLDataType) * ps->size);//头插ps->a[0] = x;ps->size++;*/SLInsert(ps, 0, x);
}void SLPopFront(SL* ps) // 头删
{assert(ps);/*assert(ps->size > 0);memmove(&(ps->a[0]), &(ps->a[1]), sizeof(SLDataType) * ps->size);ps->size--;*/SLErase(ps, 0);
}//顺序表查找
int SLFind(SL* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (x == ps->a[i]){return i;}}return -1;
}// 顺序表在pos位置插入x
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);// 插入时 = size 相当于尾插SLCheckCapacity(ps);//挪动memmove(&(ps->a[pos + 1]), &(ps->a[pos]), sizeof(SLDataType) * (ps->size - pos));//插入ps->a[pos] = x;ps->size++;
}// 顺序表删除pos位置的值
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//覆盖memmove(&(ps->a[pos]), &(ps->a[pos + 1]), sizeof(SLDataType) * (ps->size - pos - 1));ps->size--;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"void TestSeqList1()//第一组测试用例
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPushBack(&s, 5);SLPushBack(&s, 6);SLPushBack(&s, 7);SLPushBack(&s, 8);SLPrint(&s);SLPopBack(&s);SLPopBack(&s);SLPrint(&s);SLPushFront(&s, 9);SLPushFront(&s, 10);SLPushFront(&s, 11);SLPushFront(&s, 12);SLPushFront(&s, 13);SLPushFront(&s, 14);SLPrint(&s);SLPopFront(&s);SLPopFront(&s);SLPopFront(&s);SLPrint(&s);SLInsert(&s, 3, 30);SLPrint(&s);SLErase(&s, 3);SLPrint(&s);int pos = SLFind(&s, 3);if (pos == -1){printf("没找到\n");}else{printf("找到了,下标是:%d", pos);}SLDestroy(&s);
}int main()
{TestSeqList1();return 0;
}
相关文章:
顺序表——C语言实现
目录 一、线性表 二、顺序表 1.实现动态顺序表 SeqList.h SeqList.c Test.c 问题 经验:free 出问题,2种可能性 解决问题 (2)尾删 (3)头插,头删 (4)在 pos 位…...
OpenCV 图形API(21)逐像素操作
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在OpenCV的G-API模块中,逐像素操作指的是对图像中的每个像素单独进行处理的操作。这些操作可以通过G-API的计算图(Graph …...
车载联网终端4G汽车TBOX介绍定义与概述
汽车 TBOX(Telematics Box)是专为汽车设计的远程通信终端设备,属于车联网系统的关键组成部分。车联网系统一般包含主机、汽车 T - BOX、手机 APP 及后台系统。融合了车身网络和 4G 无线通信技术,为汽车提供丰富的 Telematics 服务…...
CentOS无法安装Vim文本编辑器问题以及解决方法
1.问题一:用户权限不够 解决方法一:切换到root用户 解决方法二:给本用户添加权限 2.问题二:镜像源问题:官方镜像源可能已经失效 解决方法: 1. 检查网络连接 2. 检查和配置 DNS 3. 更换镜像源&#…...
Kettle如何与应用集成
Kettle(Pentaho Data Integration,PDI)可以通过多种方式与应用程序集成,以下是7种主流方法及具体实现示例: 一、命令行调用(最基础) # 执行转换(Transformation) ./pan.…...
Pytorch torch.nn.utils.rnn.pad_sequence 介绍
torch.nn.utils.rnn.pad_sequence 是 PyTorch 中一个用于填充序列的实用函数,它主要用于处理长度不一的序列数据,将这些序列填充到相同的长度,以便能将它们组合成一个批量(batch)输入到神经网络中。以下是详细介绍&…...
4.7正则表达式
1.字符匹配 一般字符匹配自身. 匹配任意字符(换行符\n除外),一个点占一位\转义字符,使其后一个字符改变原来的意思(\.就是.)[......]字符集,对应的位置可以是字符集中的任意字符.字符集中的字符可以逐个列出,也可以给出范围如[abc]或[a-c] [^abc] 表示取反…...
CogPatInspectTool工具
CogPatInspectTool是康耐视中的一种模板比对的视觉检测工具,主要用于产品不良检测。其核心功能是通过将输入图像与预先训练好的模板进行对比,识别出两者之间的差异,并生成高亮差异图,从而判断产品是否存在缺陷。 效果图 CogPatIn…...
牛客周赛 + 洛谷刷题
秘藏 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N 200010; ll a[N], b[N]; int n, k; ll dp[2][N];//dp[i][j]是在i界中取了j之前的最大值 int main(){ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);cin >> n >&…...
【数据结构】图论存储革新:十字链表双链设计高效解决有向图入度查询难题
十字链表 导读一、邻接表的优缺点二、十字链表2.1 结点结构2.2 原理解释2.2.1 顶点表2.2.2 边结点2.2.3 十字链表 三、存储结构四、算法评价4.1 时间复杂度4.2 空间复杂度 五、优势与劣势5.1 优势5.2 劣势5.3 特点 结语 导读 大家好,很高兴又和大家见面啦ÿ…...
【JavaScript】十五、事件对象与环境对象
文章目录 1、事件对象1.1 获取事件对象1.2 常用属性1.3 案例:回车发布评论 2、环境对象this3、回调函数4、案例:tab切换5、案例:全选文本框📖 1、事件对象 事件对象: 也是个对象,object,里面存…...
OJ--第N个泰波那契数列
1137. 第 N 个泰波那契数 - 力扣(LeetCode) 1 题干部分 2 拆解 1 状态表示:dp[i] 2 状态转移方程:dp[i]dp[i-1]dp[i-2]dp[i-3] 3 初始化:让dp[0]0,dp[1]dp[2]1 4 填表顺序:从dp[3]开始填从左往右填 5 返回值:dp[n]即为返回的…...
Python从入门到高手8.1节-元组类型详解
目录 8.1.1 理解元组类型 8.1.2 元组的类型名 8.1.3 元组的定义 8.1.4 元组的解包 8.1.5 元组是可迭代的 8.1.6 假期就这么结束了 8.1.1 理解元组类型 元组与列表有着相同的数据结构,区别在于,元组是不可变的数据类型,而列表是可变的数…...
使用 Qt 和 OBS 工具检测系统硬件编码器支持情况(NVENC、QSV、AMF)
在开发涉及视频处理的软件时,判断系统是否支持硬件加速编码器(如 NVIDIA NVENC、Intel QSV、AMD AMF)对于性能优化至关重要。本文将介绍如何结合 Qt 与 OBS Studio 附带的小工具程序,实现一个完整、异步且不会卡住 UI 的硬件加速检测模块。 一、背景与目标 硬件加速编码器…...
Python爬虫生成CSV文件的完整流程
引言 在当今数据驱动的时代,网络爬虫已成为获取互联网数据的重要工具。Python凭借其丰富的库生态系统和简洁的语法,成为了爬虫开发的首选语言。本文将详细介绍使用Python爬虫从网页抓取数据并生成CSV文件的完整流程,包括环境准备、网页请求、…...
图论:多源最短路
多源最短路 B3647 【模板】Floyd - 洛谷 #include<iostream> #include<cstring> using namespace std;const int N 110; int f[N][N]; int n, m;int main() {memset(f, 0x3f, sizeof(f));//对于重边的处理取较小值,所以要把全部都初始化成无穷大&…...
2024年已备案大模型发展趋势分析
2024年已备案大模型发展趋势分析 随着生成式人工智能技术的快速发展,其在各个领域的应用逐渐深入。为了规范和促进生成式人工智能服务的健康发展,国家互联网信息办公室发布了《生成式人工智能服务已备案信息》。本文将基于已备案信息,分析生成式人工智能服务的发展趋势,并…...
spring功能汇总
1.创建一个dao接口,实现类;service接口,实现类并且service里用new创建对象方式调用dao的方法 2.使用spring分别获取dao和service对象(IOC) 注意 2中的service里面获取dao的对象方式不用new的(DI) 运行测试: 使用1的方式创建servic…...
Transformer - Feed Forward前馈网络
一、数学原理 1. 前馈神经网络公式 2. Dropout公式 二、代码实现 import math import torchimport torch.nn as nnclass FeedForward(nn.Module):def __init__(self, d_model, dff, dropout):super().__init__()self.W1 nn.Linear(d_model, dff)self.W2 nn.Linear(dff, d_mo…...
Compose Multiplatform+Kotlin Multiplatfrom 第五弹跨平台 截图
截图功能 Compose MultiplatformKotlin Multiplatfrom下实现桌面端的截图功能,起码搞了两星期,最后终于做出来了,操作都很流畅,截取的文件大小也正常,可参考支持讨论! 功能效果 代码实现 //在jvmMain下创…...
算法题(119):高精度减法
审题: 本题高精度减法主要是要区分正负号,然后进行模拟 思路: 方法一:模拟法 首先本题需要我们利用字符串进行大数相减 第一步:区分s1和s2谁更大 先从数的位数进行判断,然后再从高到低的位数进行判断 第二步…...
使用成员函数指针数组简化C++类中的操作
使用成员函数指针数组简化C类中的操作 在C编程中,我们常常会遇到需要对一组相似的操作进行处理的情况。例如,在一个游戏引擎中,你可能希望角色能够执行一系列的动作,如行走、跳跃或攻击等。为了简化这些操作的管理和调用…...
WebGL数学手记:矩阵基础
一、矩阵的定义 矩阵,数学术语。在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合。 1.英文发音(Matrix) Matrix的发音类似于中文的[美吹克斯],知道它的发音。方便后期看教程时…...
Python爬取数据(二)
一.example2包下的 1.re模块的compile函数使用 import repatternre.compile(r\d) print(pattern) 2.match的方法使用 import re patternre.compile(r\d) # m1pattern.match(one123twothree345four) #参数2:指定起始位置(包含),参数3:终止位置(包含),…...
我的NISP二级之路-01
目录 一.SSE-CMM系统安全工程-能力成熟度模型(Systems Security Engineering - Capability Maturity Model) 二.ISMS 即信息安全管理体系(Information Security Management System),是一种基于风险管理的、系统化的管理体系 三.Kerberos协议 1. 用户登录与 AS 请求 2…...
自制简易 Shell:像搭建积木小屋一样打造命令交互小天地
目录 准备工作:搭建小屋的材料 打造小屋的 “身份牌” 接收指令:小屋的 “对讲机” 拆解指令:把大任务拆成小积木 执行指令:小屋的 “行动队” 特殊指令:小屋的 “特色功能” 小屋的日常运转 完整代码 啥是 …...
WEB安全--内网渗透--利用Net-NTLMv2 Hash
一、前言 在前两篇文章中分析了NTLM协议中Net-NTLMv2 Hash的生成、如何捕获Net-NTLMv2 Hash,现在就来探讨一下在内网环境中,如何利用Net-NTLMv2 Hash进行渗透。 二、Net-NTLM Hash的破解 工具:hashcat 原理:利用其内部的字典对…...
MySQL 数据库操作指南:从数据库创建到数据操作
关键词:MySQL;数据库操作;DDL;DML 一、引言 MySQL 作为广泛应用的关系型数据库管理系统,对于开发人员和数据库管理员而言,熟练掌握其操作至关重要。本文章通过一系列 SQL 示例,详细阐述 MySQL…...
从传递函数到PID控制器
在过程控制中,按偏差的比例(P,Proportional)、积分(I,Integral)和微分(D,Differential)进行控制的PID控制器(亦称PID调节器)是应用最为…...
抓wifi无线空口包之Ubuntu抓包(二)
一、设置网卡信道和频段,并抓包 1、使用iwconfig查看自己机器的无线网卡名称 wangwang-ThinkCentre-M930t-N000:~$ iwconfig lo no wireless extensions. eno1 no wireless extensions. enxc8a3624ab329 no wireless extensions. wlx90de80d1b5b1 IE…...
使用protobuf编译提示无法打开包括文件: ‘absl/log/absl_log.h’: No such file or directory
问题原因 Protobuf 依赖 Abseil: Protobuf 3.20 版本开始依赖 Abseil,但你的系统未正确安装或配置 Abseil。 头文件路径未包含: 编译器找不到 absl/log/absl_log.h,可能是因为 Abseil 未正确安装或未在项目中设置包含路径。 …...
深入浅出Java 锁 | 源码剖析 | 万字解析
目录 硬件内存结构&Java内存模型 硬件内存结构 Java内存模型(JMM) JMM中三大特性:原子性、有序性、可见性 Java中有哪些锁? Java中锁可以分成悲观锁和乐观锁的实现。 乐观锁和悲观锁的区别,乐观锁一定好嘛&…...
java流程控制12:流程控制练习
流程控制练习 打印三角型 package com.zheng.struct;public class TestDemo {public static void main(String[] args) {//打印三角形 5行for(int i1;i<5;i){for(int j5;j>i;j--){System.out.print(" ");}for(int j1;j<i;j){System.out.print("*&quo…...
JAVA:ByteBuddy 动态字节码操作库的技术指南
1、简述 ByteBuddy 是一个功能强大的 Java 字节码操作库,可以帮助开发者在运行时动态生成和修改类,而无需直接接触复杂的 ASM API。它被广泛应用于框架开发、AOP(面向切面编程)、代理类生成、性能监控等领域。 2、ByteBuddy 的优…...
C语言学习记录(13)自定义类型:结构体
一、结构体变量的声明、创建和初始化 1.结构体变量的声明 结构体变量我们学操作符的时候就顺带讲了一点了,因为当时讲了结构体成员变量访问操作符.。 结构体变量不像int、float这种内置类型的,一旦创建,系统就知道这是干啥的,结…...
rtthread 软件SPI驱动, 支持mode0~3,MSB,LSB
rtthread的软件模拟SPI用的上层PIN驱动写,由于经过层层封装,时钟频率并不会太高,200MHz的MCU跑不到1MHz的时钟频率。所以最好是在底层就模拟好,给上层用。 头文件 struct io_poSOFT {gpio_type *port;uint16_t pin; }; typedef …...
C++自学笔记——动态创建对象
动态创建对象 1. 什么是动态创建对象? 在学习之前的知识点时,我们知道有静态存储期和自动存储期。 静态存储期的对象在程序的整个生命周期内都存在,全局变量和static修饰的局部变量都属于这一类。自动存储期的对象,这些对象在函…...
35.[前端开发-JavaScript基础]Day12-for循环中变量-华为商城-商品列表-轮播图
for循环中监听函数中打印变量 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"wi…...
详细描述以太坊的gas、gaslimit、gasPrice
目录 一、Gas 是什么? ✅ 简要定义: 🧠 举例理解: 二、Gas Limit 是什么? ✅ 简要定义: 分两种: 举例说明: 三、Gas Price 是什么? ✅ 简要定义: 为什么它重要? 示例: 四、 EIP-1559 后的新机制(伦敦升级) 三个要素: 五、额外技巧(开发实用) 本文…...
【Java】Maven
一、概念 是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建。 二、Maven坐标 <groupId>com.itheima</groupId><artifactId>maven-project01</artifactId>&…...
PageCache
目录 一、PageCache的具体过程 二、具体实现代码 一、PageCache的具体过程 页缓存主要解决的是内存外碎片问题,并且直接和系统调用打交道。 申请过程如下: 当中心缓存中没有内存时,会去页缓存申请一个span结构,要经过下面几步: (1…...
Vue3实战五、面包屑,收缩菜单,高亮暗黑主题切换,全屏功能实现
目录 面包屑,收缩菜单,黑夜白夜样式,全屏功能实现收缩菜单按钮结合pinia功能实现第一步、定义布局配置的数据类型第二步、创建布局状态管理文件第三步、使用布局配置状态第四步、进行展开/收起左侧菜单逻辑第五步、动态切换左侧菜单宽度样式第六步、动态…...
Linux内核设计——(二)进程调度
目录 一、进程调度简介 二、多任务 三、调度器 3.1 I/O消耗型和处理器消耗型进程 3.2 进程优先级 3.3 CFS算法 3.4 实时调度策略 3.5 SCHED_FIFO 3.6 SCHED_RR 3.7 调度器入口 四、上下文切换 4.1 睡眠和唤醒 4.2 need_resched标志 4.3 用户抢占 4.4 内核抢占 一…...
【C++初阶】--- string类模拟实现
1.基础函数 1.1成员函数 成员函数主要是_str、_size、_capacity这三个。npos是size_t 的最大值,用于当作后续成员函数的参数的缺省值。 class string { private:char* _str nullptr;//指向字符串的指针size_t _size 0;//字符串长度size_t _capacity 0;//空间大小static c…...
Pythia 使用说明
Pythia 是一个由非营利研究组织 EleutherAI 开发的开源语言模型套件,专注于透明性和可复现性。它是为了推动自然语言处理(NLP)领域的开放研究而设计,尤其在模型训练过程和性能分析方面提供了详尽的文档和数据。 Pythia 的核心特点…...
python:获取某路径下所有图片的名称
可以使用 Python 的 os 模块或者 pathlib 模块来获取指定路径下所有图片的名称。以下是使用这两种方法实现的代码示例: 使用 os 模块 import osdef get_image_names_os(path):image_extensions (.jpg, .jpeg, .png, .gif, .bmp)image_names []for root, dirs, f…...
一个开源的 VS Code 大模型聊天插件:Light-at
这篇文章是一个开发杂谈。对于有经验的开发者来说,可能这个项目并不算特别复杂或者高技术,只是对我个人来说算一个里程碑,因此写篇杂谈文章记录一下。也许也能给起步者一些参考。 项目地址:https://github.com/HiMeditator/light-…...
图论学习笔记2
请先阅读图论学习笔记 1。 在这篇文章里,我们将继续以前 tarjan 求解的强连通分量和双连通分量,讲解其缩点相关内容。 也会讲解一些特殊的图:基环树与仙人掌图、最小树形图。 缩点 我们知道,将强连通分量、双连通分量缩点之后…...
蓝桥杯备赛---真题训练之15届省赛产品360度展示
题目 介绍 在电子商务网站中,用户可以通过鼠标或手势交互实现 360 度全方位查看产品,提升用户体验。现在需要你设计一个 Pipeline 管道函数,用于控制 360 度展示产品的动画序列,通过管道连接各个动画步骤,使产品以流畅…...
图论:单源最短路(BF算法+迪杰斯特拉算法+spfa算法)
单源最短路 概念 dijkstra实现(解决不了负权值) P3371 【模板】单源最短路径(弱化版) - 洛谷 #include<iostream> #include<vector> #include<cstring> using namespace std;typedef pair<int, int> PII…...