C语言数据结构之顺序表
目录
1.线性表
2.顺序表
2.1.静态顺序表
2.2.动态顺序表
2.2.1.初始化
2.2.2.清空顺序表
2.2.3.扩容+尾插
2.2.4.尾出函数
2.2.5.头插函数
2.2.6.头出函数
2.2.7.在中间位置插入
2.2.8.删除中间位置数据
2.2.9.查找函数
2.2.10.总结
3.OJ例题
3.1.合并两个有序数组
3.2.删除有序数组中的重复项
3.3.移除数组元素
4.代码
4.1 SeqList.h文件
4.2.SeqList.c文件
1.线性表
线性表式n个具有相同特性的数据元素的有限序列。应用广泛,常见的有:顺序表、链表、栈、队列、字符串……。
线性性表在逻辑上是一条连续的条线;但在内存中是不一定是连续存储的,在存储的时候通常以数组和链式形式存储。
2.顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般使用数组存储。在数组的基础上完成数据的增删查改。
2.1.静态顺序表
#define N 10
typedef int SLDataType;//此时定义的存储数据类型是int,也可以定义结构体
//等等数据类型 int 也可以换成 double char
//静态顺序表 内存空间固定,申请空间少了,不够用,多了用不完
struct SeqList
{SLDataType a[N]; //定长数组int size; //有效数据个数
};
静态的通讯录和其相似,但是通讯录存储的数据类型是一种结构体;静态的特点是:开辟空间完全依靠经验,后续无法自主调整。
2.2.动态顺序表
typedef int SLDataType;
//动态顺序表 按需申请空间
struct SeqList
{SLDataType* a; //开始存储的起始地址,可以看作为数组名int size; //有效数据个数int capacity; //空间容量
};
动态顺序表可以自主调整空间大小,空间不足的情况下,可以realloc向堆区申请内存空间,当然动态顺序表初始换使用malloc函数申请空间。
2.2.1.初始化
最开始的初始化思想是,所空间容量和有效数据数置为0,指针置为NULL(空指针)。
void SeqInit(SL* pc)
{assert(pc);pc->a = NULL;pc->size = 0;pc->capacity = 0;printf("初始化成功");
}
但是动态顺序表必须自带点儿空间,使用malloc函数向内存申请空间。INIT_CAPACITY暂定为3。
void SeqInit2(SL* pc)//形参是实参的拷贝;形参的修改无法作用在实参上,因此要用地址传值
{ assert(pc); //其SL结构体数个整体,(SLDataType*)pc = (SLDataType*)malloc(sizeof(SLDataType)*INIT_CAPACITY);if (pc->a == NULL){perror("malloc fail");return;}pc->capacity = INIT_CAPACITY;//使用#define 定义任意大小 pc->size = 0;printf("初始化成功");
}
2.2.2.清空顺序表
在顺序表使用完,需要将开辟的空间释放,返还给操作系统,使用free函数释放申请的空间;我们申请的内存空间只有使用权。
void SLDestroy(SL* pc)
{assert(pc);free(pc->a);//开的空间必须整体释放,不能一块儿一块释放pc->a = NULL;pc->size = pc->capacity = 0;if(pc->a == NULL)printf("清除成功");
}
free函数在使用时出现问题
- 指针是野指针,不指向任何空间。
- fres释放指针不是起始位置指针,如果对开辟的指针进行处理之后
- pc->a[i]数组指向的空间越界,申请的空间不足且不扩容;
- size的大小超过了capacity(容量)就是越界,若是size越界了,说明空间开辟少了。
2.2.3.扩容+尾插
在输入数据之前,要先检查顺序表的容量是否已满,若空间满了就使用realloc扩容;若没有满就输入数据就可以。这里每次扩容将会把空间扩大二倍。
将X放入下面数据的尾部就是尾插
void SLPushBack(SL* pc, SLDataType x)
{//扩容if (pc->capacity == pc->size){SLDataType* tmp = (SLDataType*)realloc(pc->a, sizeof(SLDataType)*INIT_CAPACITY * 2);//扩充二倍if (pc->a == NULL){perror("realloc fail");return ;}pc->a = tmp;pc->capacity *= 2;printf("扩容成功\n");}pc->a[pc->size++] = x;
}
realloc函数的使用如果没有 pc->a = tmp;可能会出错,realloc只会申请连续函数的使用权,若后续的内存不够,realloc将会重新申请一块儿内存,然后将新的地址赋给tmp,那么pc->a指向的位置,再次访问就是非法访问了;若是直接开辟,则问题还不明显,若是异地开辟,则会直接报错。
2.2.4.尾出函数
尾出函数较为简单,只需要将size(有效数据个数)减去1就可以了;当然在进行删除之前就要判断顺序表中书否有数据(size是否为0);
//尾出
void SLPopBack(SL* pc)
{assert(pc->size > 0);//方式1报错if (pc->size == 0) //方式2return;pc->size--;
}
在使用方式1:assert函数判断size是否大于0;如果大于0为真,执行下一步;若小于0为假,报错,而且会有具体的位置。assert函数会让程序维护更加简单。
若使用方式二报错,程序运行窗口会闪烁,一会儿会自动结束进程。
2.2.5.头插函数
头插函数在输入数据之前,要先检测是否要进行扩容,因此可以将扩容另写一个函数,再复用扩容函数;然后对位于最后的数据开始依次向后一个位置挪动。
void SLPushFront(SL* pc, SLDataType x)
{assert(pc);//检查空间SLCheckCapacity(pc);//挪动数据int end = pc->size - 1;while (end >= 0){pc->a[end + 1] = pc->a[end];end--;}//赋值pc->a[0] = x;//有效数据+1pc->size++;
}
2.2.6.头出函数
将第二个数据覆盖第一个数据,第三个数据覆盖第二个数据,然后有效数据减去一。
void SLPopFront(SL* pc)
{assert(pc);assert(pc->size > 0);int i = 0;for (i = 0; i < pc->size; i++){pc->a[i] = pc->a[i + 1];}pc->size--;
}
2.2.7.在中间位置插入
中间位置的插入就是确定位置pos在哪里,确定pos变量是否合规;判断是否有多余的空间;然后将最后一个数据向后再移动一个位置,依次移动。
//在某个位置插入
void SLInsert(SL* pc, int pos, SLDataType x)
{//判断指针和位置是否有效assert(pc);assert(pos >= 0 && pos <= pc->size);//判断是否扩容SLCheckCapacity(pc);//挪动数据int end = pc->size - 1;while (pos <= end){pc->a[end + 1] = pc->a[end];end--;}//插入数据pc->a[pos] = x;pc->size++;
}
我们可以根据这个函数对尾插和头插函数进行修改,复用上述函数。
头插函数
头插函数的位置就是0 pc->a[0].
void SLPushFront(SL* pc, SLDataType x)
{assert(pc);//检查空间SLCheckCapacity(pc);//挪动数据SLInsert(pc, 0, x);
}
尾插函数
void SLPushBack(SL* pc, SLDataType x)
{assert(pc);SLInsert(pc, pc->size, x);
}
2.2.8.删除中间位置数据
//删除某一个位置的数据
void SLErase(SL* pc, int pos)
{assert(pc);assert(pos >= 0 && pos < pc->size);int begin = pos + 1;while (begin < pc->size){pc->a[begin-1] = pc->a[begin];begin++;}pc->size--;
}
确定位置后,我们将其后面的数据依次递进,程序中的pos是数组的下标,从0开始。
当然上面的函数也可以复用
头出函数
void SLPopFront(SL* pc)
{SLErase(pc,0);
}
尾出函数
void SLPopBack(SL* pc)
{SLErase(pc, pc->size-1);
}
2.2.9.查找函数
将顺序表中的元素遍历一边,就可以找到了。
//查找函数
int SLFind(SL* pc, SLDataType x)
{assert(pc);int i = 0;for (i = 0; i < pc->size; i++){if (pc->a[i] == x){return i + 1;}}return -1;
}
2.2.10.总结
在插入和删除一组数据的情况下,按照最坏的时间复杂度来说,尾插和尾出的时间复杂度是O(1);头插和头出的时间复杂度是O(N);中间插入和删除的时间复杂度也是O(N);因此在处理数据的时候,在好用的还是的尾插和尾出。
3.OJ例题
3.1.合并两个有序数组
88. 合并两个有序数组 - 力扣(LeetCode)
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{int end1 = m - 1;int end2 = n -1;int dst = m + n -1;while(end1 >= 0&& end2 >= 0){if(nums1[end1]>nums2[end2]){nums1[dst--]=nums1[end1--];}else{nums1[dst--]=nums2[end2--];}}while(end2>=0){nums1[dst--]=nums2[end2--];}
}
题解思路:
目标将两个数组合并成有序的数组,比较大小,nums1中有效数有m个元素,而长度为m+n个,足够容下nums2;数组nums1中的前面不能覆盖,所以就倒叙排列了。
3.2.删除有序数组中的重复项
26. 删除有序数组中的重复项 - 力扣(LeetCode)
int removeDuplicates(int* nums, int numsSize)
{int src = 1;int dst = 0;while(src < numsSize){if(nums[src] == nums[dst]){src++;}else{dst++;nums[dst] = nums[src++];}}return dst+1;
}
使用双指针,这里的双指针指的是两个下边;dst为目标指针,src为递进指针,src中的数组复制到src中;首先判断两个指针指向的数据是否一样,不一样复制;注意的是dst要增加一位;因为原来指向的位置不一样的;一样的话,src指针++,寻找下一个不一样的数据。
3.3.移除数组元素
27. 移除元素 - 力扣(LeetCode)
int removeElement(int* nums, int numsSize, int val)
{int src = 0;int dst = 0;while(src < numsSize){if(nums[src] != val){nums[dst++] = nums[src++];}else{src++;}}return dst;
}
使用双指针,从数组起始位置开始,和原来项相等便src++,dst保持不动,不相等的时候直接将val所占据的位置覆盖。
4.代码
4.1 SeqList.h文件
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>//#define N 10
//typedef int SLDataType;//此时定义的存储数据类型是int,也可以定义结构体
等等数据类型 int 也可以换成 double char
静态顺序表 内存空间固定,申请空间少了,不够用,多了用不完
//struct SeqList
//{
// SLDataType a[N]; //定长数组
// int size; //有效数据个数
//};
#define INIT_CAPACITY 3
typedef int SLDataType;
//动态数组
struct SeqList
{SLDataType* a; //开始存储的起始地址,可以看作为数组名int size; //有效数据个数int capacity; //空间容量
};
typedef struct SeqList SL;
//初始化
void SeqInit(SL* pc);
//扩容+初始化
void SeqInit2(SL* pc);
//清空函数
void SLDestroy(SL* pc);
//尾插函数
void SLPushBack(SL* pc, SLDataType x);
//输出函数
void SLPrint(SL* pc);
//尾出函数
void SLPopBack(SL* pc);
//扩容函数
void SLCheckCapacity(SL* pc);
//前插函数
void SLPushFront(SL* pc, SLDataType x);
//头删函数
void SLPopFront(SL* pc);
//在某个位置插入
void SLInsert(SL* pc, int pos, SLDataType x);
//删除某一个位置的数据
void SLErase(SL* pc, int pos);
//查找函数
int SLFind(SL* pc, SLDataType x);
4.2.SeqList.c文件
#include "SeqList.h"//初始化
void SeqInit(SL* pc)
{pc->a = NULL;pc->size = 0;pc->capacity = 0;printf("初始化成功");
}
//初始化开辟空间
void SeqInit2(SL* pc)//形参是实参的拷贝;形参的修改无法作用在实参上,因此要用地址传值
{ //其SL结构体数个整体,assert(pc);(SLDataType*)pc->a = (SLDataType*)malloc(sizeof(SLDataType)*INIT_CAPACITY);if (pc->a == NULL){perror("malloc fail");return;}pc->capacity = INIT_CAPACITY;pc->size = 0;printf("初始化成功\n");
}
//清除函数
void SLDestroy(SL* pc)
{assert(pc);free(pc->a);pc->a = NULL;pc->size = pc->capacity = 0;if(pc->a == NULL)printf("\n清除成功");
}
//尾插函数
void SLPushBack(SL* pc, SLDataType x)
{assert(pc);//扩容SLInsert(pc, pc->size, x);//SLCheckCapacity(pc); //pc->a[pc->size++] = x;
}
//输出函数
void SLPrint(SL* pc)
{int i = 0;for (i = 0; i < pc->size; i++){printf("%d ",pc->a[i]);}printf("\n");
}
//尾出函数
void SLPopBack(SL* pc)
{SLErase(pc, pc->size-1);
}
//扩容函数
void SLCheckCapacity(SL* pc)
{if (pc->capacity == pc->size){SLDataType* tmp = (SLDataType*)realloc(pc->a, sizeof(SLDataType)*INIT_CAPACITY * 2);//扩充二倍if (pc->a == NULL){perror("realloc fail");return;}pc->a = tmp;pc->capacity *= 2;printf("扩容成功\n");}}
//头插函数
void SLPushFront(SL* pc, SLDataType x)
{assert(pc);//检查空间SLCheckCapacity(pc);//挪动数据SLInsert(pc, 0, x);
}
//头出函数
void SLPopFront(SL* pc)
{SLErase(pc,0);
}
//在某个位置插入
void SLInsert(SL* pc, int pos, SLDataType x)
{//判断指针和位置是否有效assert(pc);assert(pos >= 0 && pos <= pc->size);//判断是否扩容SLCheckCapacity(pc);//挪动数据int end = pc->size - 1;while (pos <= end){pc->a[end + 1] = pc->a[end];end--;}//插入数据pc->a[pos] = x;pc->size++;
}
//删除某一个位置的数据
void SLErase(SL* pc, int pos)
{assert(pc);assert(pos >= 0 && pos < pc->size);int begin = pos + 1;while (begin < pc->size){pc->a[begin-1] = pc->a[begin];begin++;}pc->size--;
}
//查找函数
int SLFind(SL* pc, SLDataType x)
{assert(pc);int i = 0;for (i = 0; i < pc->size; i++){if (pc->a[i] == x){return i + 1;}}return -1;
}
相关文章:
C语言数据结构之顺序表
目录 1.线性表 2.顺序表 2.1.静态顺序表 2.2.动态顺序表 2.2.1.初始化 2.2.2.清空顺序表 2.2.3.扩容+尾插 2.2.4.尾出函数 2.2.5.头插函数 2.2.6.头出函数 2.2.7.在中间位置插入 2.2.8.删除中间位置数据 2.2.9.查找函数 2.2.10.总结 3.OJ例题 3.1.合…...
【Git】合并冲突
合并冲突 可是,在实际分支合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。 为了演示这问题,创建一个新的分支 dev1 ,并切换至目标分支,我们可以使用 git checkout -b dev1 一步…...
【每日学点HarmonyOS Next知识】Web跨域资源、Web长按菜单、Web拦截请求、禁止录屏、Base64图片宽高
1、HarmonyOS Web组件本地资源跨域问题? 关于资源跨域问题的解决,可以参考以下官网文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/web-cross-origin-V5 方法一 为了使Web组件能够成功访问跨域资源,开…...
高效数据分析实战指南:Python零基础入门
高效数据分析实战指南 —— 以Python为基石,构建您的数据分析核心竞争力 大家好,我是kakaZhui,从事数据、人工智能算法多年,精通Python数据分析、挖掘以及各种深度学习算法。一直以来,我都发现身边有很多在传统行业从…...
【语料数据爬虫】Python爬虫|批量采集征集意见稿数据(1)
前言 本文是该专栏的第5篇,后面会持续分享Python爬虫采集各种语料数据的的干货知识,值得关注。 在本文中,笔者将主要来介绍基于Python,来实现批量采集“征集意见稿”数据。同时,本文也是采集“征集意见稿”数据系列的第1篇。 采集相关数据的具体细节部分以及详细思路逻辑…...
电力场景绝缘子缺陷分割数据集labelme格式1585张4类别
数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):1585 标注数量(json文件个数):1585 标注类别数:4 标注类别名称:["broken part","broken insulat…...
《C++ 构造、拷贝构造与析构函数:对象的诞生、克隆与消逝之旅》
类的6个默认成员函数 构造函数 是对一个对象实例化时的初始化 例如在C语言中写的堆的时候要初始化StackInit,而c祖师爷写的构造函数本质上就是自动调用初始化。 构造函数默认构造函数自己写的(符合规定的显示表达式) 注:一般情况下…...
uniapp uniCloud引发的血案(switchTab: Missing required args: “url“)!!!!!!!!!!
此文章懒得排版了,为了找出这个bug, 星期六的晚上我从9点查到0点多,此时我心中一万个草泥马在崩腾,超级想骂人!!!!!!!!! uniCloud 不想…...
【论文阅读】VAD: Vectorized Scene Representation for Efficient Autonomous Driving
一、介绍 VAD是华科团队设计的一个端到端无人驾驶框架,针对传统的无人驾驶框架的模块化设计的问题,该算法使用向量化的策略进行了端到端的实现。传统的模块化设计使得感知模块完全依赖于感知模块的计算结果,这一解耦实际上从规划模块的角度损…...
uniapp版本加密货币行情应用
uniapp版本加密货币行情应用 项目概述 这是一个使用uniapp开发的鸿蒙原生应用,提供加密货币的实时行情查询功能。本应用旨在为用户提供便捷、实时的加密货币市场信息,帮助用户随时了解市场动态,做出明智的投资决策。 应用采用轻量级设计&a…...
使用 Java 执行 SQL 语句和存储过程
使用 Java 执行 SQL 语句和存储过程,通常有两种主要的方式:使用 JDBC(Java Database Connectivity)或者通过框架如 Spring Data JPA、MyBatis 等。 1. 使用 JDBC 执行 SQL 语句 JDBC 是 Java 操作数据库的标准 API。以下是通过 …...
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
在算法学习中,深度优先搜索(DFS)是一种常用的图搜索算法,通过递归或栈实现,适合路径搜索、连通性、拓扑排序、回溯、生成、环路检测、强连通分量和可达性等问题。本文将介绍如何利用深度优先搜索解决“妖怪和尚过河问题…...
大白话JavaScript闭包实现原理与在实际开发中的应用场景
大白话JavaScript闭包实现原理与在实际开发中的应用场景 答题思路 解释闭包的概念:先简单直白地说明闭包是什么,让读者对闭包有一个初步的认识。阐述闭包的实现原理:详细讲解闭包是如何形成的,涉及到函数作用域、变量的生命周期…...
【redis】数据类型之geo
Redis的GEO数据类型用于存储地理位置信息(如经纬度),并提供高效的地理位置查询功能(如计算两地距离、搜索附近地点等)。其底层基于Sorted Set(有序集合)实现,通过Geohash编码将经纬度…...
C++后端服务器开发技术栈有哪些?有哪些资源或开源库拿来用?
一、 C后台服务器开发是一个涉及多方面技术选择的复杂领域,特别是在高性能、高并发的场景下。以下是C后台服务器开发的一种常见技术路线,涵盖了从基础到高级的技术栈。 1. 基础技术栈 C标准库 C11/C14/C17/C20:使用现代C特性,如…...
第五次CCF-CSP认证(含C++源码)
第五次CCF-CSP认证 第一道(easy)思路及AC代码 第二道(easy)思路及AC代码solution 1solution 2 第三道(mid)思路及AC代码(mid) 第一道(easy) 题目链接 思路及…...
tcp udp区别
TCP(传输控制协议) 和 UDP(用户数据报协议) 是两种常用的传输层协议,它们在数据传输方式、可靠性和应用场景等方面有显著区别。以下是它们的主要区别: 1. 连接方式 TCP:面向连接的协议。通信前需…...
驱动 AI 边缘计算新时代!高性能 i.MX 95 应用平台引领未来
智慧浪潮崛起:AI与边缘计算的时代 正悄然深植于我们的日常生活之中,无论是火热的 ChatGPT 与 DeepSeek 语言模型,亦或是 Meta 智能眼镜,AI 技术已经无形地影响着我们的生活。这股变革浪潮并未停歇,而是进一步催生了更高…...
【Keil5教程及技巧】耗时一周精心整理万字全网最全Keil5(MDK-ARM)功能详细介绍【建议收藏-细细品尝】
💌 所属专栏:【单片机开发软件技巧】 😀 作 者: 于晓超 🚀 个人简介:嵌入式工程师,专注嵌入式领域基础和实战分享 ,欢迎咨询! 💖 欢迎大家࿱…...
Linux 进程管理工具 Supervisor
介绍 Supervisor 是一个用 Python 编写的进程管理工具,旨在帮助你监控和控制多个进程。它特别适用于需要确保某些服务在服务器启动时自动运行,并且在崩溃时自动重启的场景。 写在前面: 因为现在很多第三方的包的最新版本都是基于 python3了…...
问题解决:AttributeError: ‘NoneType‘ object has no attribute ‘text‘
项目环境: 我的环境:Window10,Python3.12,Anaconda3,Pycharm2024.3.4 问题描述: 找不到’text’这个对象 部分代码: Traceback (most recent call last):File "D:\IT DateFiles\PyDate\FQ…...
Hadoop、Hive、Spark的关系
Part1:Hadoop、Hive、Spark关系概览 1、MapReduce on Hadoop 和spark都是数据计算框架,一般认为spark的速度比MR快2-3倍。 2、mapreduce是数据计算的过程,map将一个任务分成多个小任务,reduce的部分将结果汇总之后返回。 3、HIv…...
OneM2M:全球性的物联网标准-可应用于物联网中
OneM2M 是一个全球性的物联网(IoT)标准,旨在为物联网设备和服务提供统一的框架和接口,以实现设备之间的互操作性、数据共享和服务集成。OneM2M 由多个国际标准化组织(如 ETSI、TIA、TTC、ARIB 等)共同制定,目标是解决物联网领域的碎片化问题,提供一个通用的标准,支持跨…...
C++类和对象入门(三)
目录 前言 一、初始化列表 1.1定义 1.2 格式和语法 1.3与在函数内初始化的区别 1.4使用初始化列表的必要性 1.5成员变量默认值的使用(C11) 1.6初始化的先后顺序 1.7初始化列表的总结 二、类型转换 2.1内置类型转化成类类型 2.2类类型之间的相…...
Ubuntu 下 Docker 企业级运维指南:核心命令与最佳实践深度解析20250309
Ubuntu 下 Docker 企业级运维指南:核心命令与最佳实践深度解析 在当今的数字化时代,Docker 已成为企业应用部署和运维的基石。其轻量级、高效且灵活的容器化技术,为企业带来了前所未有的敏捷性和可扩展性。然而,随着容器化应用的…...
Tensorflow 2.0 GPU的使用与限制使用率及虚拟多GPU
Tensorflow 2.0 GPU的使用与限制使用率及虚拟多GPU 1. 获得当前主机上特定运算设备的列表2. 设置当前程序可见的设备范围3. 显存的使用4. 单GPU模拟多GPU环境 先插入一行简单代码,以下复制即可用来设置GPU使用率: import tensorflow as tf import numpy…...
【PyCharm】Python和PyCharm的相互关系和使用联动介绍
李升伟 整理 Python 是一种广泛使用的编程语言,而 PyCharm 是 JetBrains 开发的专门用于 Python 开发的集成开发环境(IDE)。以下是它们的相互关系和使用联动的介绍: 1. Python 和 PyCharm 的关系 Python:一种解释型、…...
动态规划:多重背包
本题力扣上没有原题,大家可以去卡码网第56题 (opens new window)去练习,题意是一样的。 56. 携带矿石资源(第八期模拟笔试) 题目描述 你是一名宇航员,即将前往一个遥远的行星。在这个行星上,有许多不同类…...
AI编程: 一个案例对比CPU和GPU在深度学习方面的性能差异
背景 字节跳动正式发布中国首个AI原生集成开发环境工具(AI IDE)——AI编程工具Trae国内版。 该工具模型搭载doubao-1.5-pro,支持切换满血版DeepSeek R1&V3, 可以帮助各阶段开发者与AI流畅协作,更快、更高质量地完…...
TensorFlow 的基本概念和使用场景
TensorFlow 是一个由 Google 开发的开源深度学习框架,用于构建和训练机器学习模型。它的基本概念包括以下几点: 张量(Tensor):在 TensorFlow 中,数据以张量的形式表示,张量可以是多维数组&#…...
gRPC学习笔记
微服务 一旦某个服务器宕机,会引起整个应用不可用,隔离性差 只能整体应用进行伸缩,浪费资源,可伸缩性差 代码耦合在一起,可维护性差 微服务架构:解决了单体架构的弊端 可以按照服务进行单独扩容 各个…...
Linux常见指令
Linux常见指令 1、ls指令2、pwd命令3、cd指令4、touch指令5、mkdir指令6、rmdir指令和rm指令7、man指令8、cp指令9、mv指令10、cat指令11、重定向12、more指令13、less指令14、head指令15、tail指令16、管道17、时间相关指令18、cal指令19、find指令20、grep指令21、zip/unzip指…...
Vue3、vue学习笔记
<!-- Vue3 --> 1、Vue项目搭建 npm init vuelatest cd 文件目录 npm i npm run dev // npm run _ 这个在package.json中查看scripts /* vue_study\.vscode可删 // vue_study\src\components也可删除(基本语法,不使用组件) */ // vue_study\.vscode\lau…...
用OpenCV写个视频播放器可还行?(C++版)
引言 提到OpenCV,大家首先想到的可能是图像处理、目标检测,但你是否想过——用OpenCV实现一个带进度条、倍速播放、暂停功能的视频播放器?本文将通过一个实战项目,带你深入掌握OpenCV的视频处理能力,并解锁以下功能&a…...
clion+arm-cm3+MSYS-mingw +jlink配置用于嵌入式开发
0.前言 正文可以跳过这段 初识clion,应该是2015年首次发布的时候, 那会还是大三,被一则推介广告吸引到,当时还在用vs studio,但是就喜欢鼓捣新工具,然后下载安装试用了clion,但是当时对cmake规…...
物联网-IoTivity:开源的物联网框架
IoTivity 是一个开源的物联网(IoT)框架,旨在为物联网设备提供互操作性、安全性和可扩展性。它由 Open Connectivity Foundation (OCF) 主导开发,遵循 OCF 的标准,致力于实现设备之间的无缝连接和通信。IoTivity 提供了一个统一的框架,支持设备发现、数据交换、设备管理和…...
Acrobat DC v25.001 最新专业版已破,像word一样编辑PDF!
在数字化时代,PDF文件以其稳定性和通用性成为了文档交流和存储的热门选择。无论是阅读、编辑、转换还是转曲,大家对PDF文件的操作需求日益增加。因此,一款出色的PDF处理软件不仅要满足多样化的需求,还要通过简洁的界面和强大的功能…...
【c++】模板进阶
在前面我们学习了模板的基础用法【c】 模板初阶-CSDN博客初步认识了函数模板和类模板,接下来让我们看看模板还有哪些进阶的应用。 非类型模板参数 之前我们用到的模板全都使用了类型参数 类型参数:表示某种数据类型(如 int、double、自定义…...
IntelliJ IDEA 2021版创建springboot项目的五种方式
第一种方式,通过https://start.spring.io作为spring Initializr的url来创建项目。 第二种方式,通过https://start.spring.io官网来直接创建springboot项目压缩包,然后导入至我们的idea中。 点击generate后,即可生成压缩包…...
数字信号处理之信号功率谱计算welch方法(分段加窗平均周期图)、Bartlett方法(周期图)(Python)
welch方法原理说明 welch方法[1]通过将数据划分为重叠的段,计算每个段的进行修改(加窗)后的周期图,然后对所有段的周期图求和进行平均,得到最终的功率谱密度。 Python和Matlab中均存在welch函数。welch函数通过配置noverlap为0,可…...
【面试】Java 基础
基础 1、Java 中几种基本数据类型什么,各自占用多少字节2、基本数据同包装类的区别3、Java 基本类型的参数传递和引用类型的参数传递有啥区别4、隐式类型转换和显式类型转换5、switch 语句表达式结果的类型6、数组的扩容方式7、面向对象三大特征8、静态变量和成员变…...
【工具使用】IDEA 社区版如何创建 Spring Boot 项目(详细教程)
IDEA 社区版如何创建 Spring Boot 项目(详细教程) Spring Boot 以其简洁、高效的特性,成为 Java 开发的主流框架之一。虽然 IntelliJ IDEA 专业版提供了Spring Boot 项目向导,但 社区版(Community Edition)…...
CTFHub-FastCGI协议/Redis协议
将木马进行base64编码 <?php eval($_GET[cmd]);?> 打开kali虚拟机,使用虚拟机中Gopherus-master工具 Gopherus-master工具安装 git clone https://github.com/tarunkant/Gopherus.git 进入工具目录 cd Gopherus 使用工具 python2 "位置" --expl…...
【Python字符串】\n是什么?它与raw字符串、多行字符串的运用有什么关系?
李升伟 整理 在Python中,\n 是换行符,用于在字符串中表示新的一行。当你在字符串中使用 \n 时,Python 会在该位置插入一个换行符,使得输出在 \n 处换行。 1. 普通字符串中的 \n 在普通字符串中,\n 会被解释为换行符…...
Linux 配置静态 IP
一、简介 在 Linux CentOS 系统中默认动态分配 IP 地址,每次启动虚拟机服务都是不一样的 IP,因此要配置静态 IP 地址避免每次都发生变化,下面将介绍配置静态 IP 的详细步骤。 首先先理解一下动态 IP 和静态 IP 的概念: 动态 IP…...
git lfs使用方法指南【在github保存100M以上大文件】
为了在 GitHub 仓库中存储超过 100MB 的大文件并避免推送失败,使用 Git LFS(Large File Storage) 是最佳解决方案。以下是详细步骤: 一、安装 Git LFS 下载并安装 Git LFS: 访问 Git LFS 官网 下载对应系统的安装包。或…...
【Linux】初识线程
目录 一、什么是线程: 重定义线程和进程: 执行流: Linux中线程的实现方案: 二、再谈进程地址空间 三、小结: 1、概念: 2、进程与线程的关系: 3、线程优点: 4、线程…...
【Linux学习笔记】Linux基本指令分析和权限的概念
【Linux学习笔记】Linux基本指令分析和权限的概念 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 文章目录 【Linux学习笔记】Linux基本指令分析和权限的概念前言一. 指令的分析1.1 alias 指令1.2 grep 指令1.3 zip/unzip 指…...
uniapp登录用户名在其他页面都能响应
使用全局变量 1、在APP.vue中定义一个全局变量,然后在需要的地方引用它; <script>export default {onLaunch: function() {console.log(App Launch)this.globalData { userInfo: {} };},onShow: function() {console.log(App Show)},onHide: fu…...
ESP8266 入门(第 2 部分):使用 AT 命令
使用 AT 命令对 WiFi 收发器ESP8266编程 本教程是上一个教程 ESP8266 入门(第 1 部分)的延续。因此,简单回顾一下,在之前的教程中,我们介绍了 ESP 模块,并学习了一些基础知识。我们还使用 FTDI 串行适配器模块制作了一个开发板,该模块可以很容易地用于使用 AT 命令和 A…...