数据结构--初识栈和队列

news2024/12/26 23:40:18

1.栈

1.1栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
在这里插入图片描述

1.2栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更有一些。因为在数组为上插入数据的代价比较小。
在这里插入图片描述
接下来我们一起用数组实现栈

定义结构体

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;//栈的容量
}ST;

定义一个STDataType类型的指针,int类型的top变量记录位置,int类型的capacity变量记录栈的容量

Stack.h文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;//栈的容量
}ST;

//栈的初始化
void STackInit(ST* ps);
//栈的销毁
void STackDestroy(ST* ps);
//入栈
void STackPush(ST* ps, STDataType x);
//出栈
void STackPop(ST* ps);
//判断是否栈空
bool STackEmpty(ST* ps);
//栈的大小
int STackSize(ST* ps);
//获取栈顶元素
STDataType STackTop(ST* ps);

Stack.c文件

#include"Stack.h"
//栈的初始化
void STackInit(ST* ps)
{
	assert(ps);
	STDataType* tmp = (STDataType*)malloc(sizeof(STDataType) * 3);
	if (tmp == NULL)
	{
		perror("STackInit(ST* ps)::malloc");
		return;
	}
	ps->a = tmp;
	ps->capacity = 3;
	ps->top = 0;//指向栈顶元素下一个位置
	//ps->a = -1;//指向栈顶元素的位置
}
//栈的销毁
void STackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->capacity = ps->top = 0;
}
//入栈
void STackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, 
			sizeof(STDataType)*ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("STackPush::realloc");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top++] = x;
}
//出栈
void STackPop(ST* ps)
{
	assert(ps);
	assert(!STackEmpty(ps));
	ps->top--;
}
//判断是否栈空
bool STackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
//栈的大小
int STackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}
//获取栈顶元素
STDataType STackTop(ST* ps)
{
	assert(ps);
	assert(!STackEmpty(ps));
	return ps->a[ps->top-1];
}

test.c文件

#include"Stack.h"
int main()
{
	ST st;
	STackInit(&st);
	STackPush(&st, 1);
	STackPush(&st, 2);
	STackPush(&st, 3);
	STackPush(&st, 4);
	STackPush(&st, 5);
	printf("当前栈的大小为:>%d\n", STackSize(&st));
	while (!STackEmpty(&st))
	{
		printf("%d ", STackTop(&st));
		STackPop(&st);
	}
	return 0;
}

代码运行的结果为:
在这里插入图片描述

2.队列

2.1队列的概念及实现

队列:只允许在一端进行插入数据操作,在另一端进行删除操作的特殊线性表,队列具有先进先出(First in First Out)入队列:进行插入操作的一端为队尾,出队列:进行删除操作的一端称为队头
在这里插入图片描述

2.2队列的实现

队列也可以使用数组和链表的结构实现,使用链表的结构更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率比较低。注意: 使用链表解结构实现,出队列操作,一定会修改头指针,如果出队列之后,队列为空,需要修改尾指针。

Queue.h文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef int QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;
//队列初始化
void QueueInit(Queue* pq);
//队列销毁
void QueueDestroy(Queue* pq);
//入队列
void QueuePush(Queue* pq, QDataType x);
//出队列
void QueuePop(Queue* pq);
//队列大小
int QueueSize(Queue* pq);
//队列判空
bool QueueEmpty(Queue* pq);
//获取队头元素
QDataType QueueFront(Queue* pq);
//获取队尾元素
QDataType QueueBase(Queue* pq);

Queue.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
//队列初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
//队列销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
//入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("QueuePush::malloc");
		return;
	}
	newnode->next = NULL;
	newnode->data = x;
	if (pq->head == NULL)
	{
		assert(pq->tail == NULL);
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}
//出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	//QNode* del = pq->head;
	//pq->head = del->next;
	//free(del);
	//if (pq->head == NULL)
	//	pq->tail = NULL;
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}
//队列大小
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}
//队列判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}
//获取队头元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}
//获取队尾元素
QDataType QueueBase(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}

test.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
int main()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePop(&q);
	QueuePush(&q, 2);
	QueuePop(&q);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);
	printf("队列元素个数为:>%d\n", QueueSize(&q));
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	return 0;
}

代码测试的结果为:
在这里插入图片描述

3.栈和队列的面试题

3.1括号匹配问题

在这里插入图片描述
代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef char STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;//栈的容量
}ST;
//栈的初始化
void STackInit(ST* ps);
//栈的销毁
void STackDestroy(ST* ps);
//入栈
void STackPush(ST* ps, STDataType x);
//出栈
void STackPop(ST* ps);
//判断是否栈空
bool STackEmpty(ST* ps);
//栈的大小
int STackSize(ST* ps);
//获取栈顶元素
STDataType STackTop(ST* ps);
//栈的初始化
void STackInit(ST* ps)
{
	//assert(ps);
	STDataType* tmp = (STDataType*)malloc(sizeof(STDataType) * 3);
	if (tmp == NULL)
	{
		perror("STackInit(ST* ps)::malloc");
		return;
	}
	ps->a = tmp;
	ps->capacity = 3;
	ps->top = 0;//指向栈顶元素下一个位置
	//ps->a = -1;//指向栈顶元素的位置
}
//栈的销毁
void STackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->capacity = ps->top = 0;
}
//入栈
void STackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, 
			sizeof(STDataType)*ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("STackPush::realloc");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top++] = x;
}
//判断是否栈空
bool STackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
//出栈
void STackPop(ST* ps)
{
	assert(ps);
	assert(!STackEmpty(ps));
	ps->top--;
}

//栈的大小
int STackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}
//获取栈顶元素
STDataType STackTop(ST* ps)
{
	assert(ps);
	assert(!STackEmpty(ps));
	return ps->a[ps->top-1];
}
 
 bool isValid(char * s)
 {
     ST st;
    STackInit(&st);
    //StackInit(&st);
     while(*s)
     {
         if(*s=='('||*s=='['||*s=='{')
         {
            STackPush(&st,*s);
         }
         else{
             //右括号比左括号多的情况
             if(STackEmpty(&st))
             {
                 STackDestroy(&st);
                 return false;
             }  
             char top=STackTop(&st);
             if((top=='('&&*s!=')')||
             (top=='['&&*s!=']')||
             (top=='{'&&*s!='}'))
             {
                STackDestroy(&st);
                 return false;
             }
             STackPop(&st);
         }
         s++;
     }
     //左括号比右括号多的情况
     bool ret =STackEmpty(&st);
     STackDestroy(&st);
     return ret;
 }

3.2用队列实现栈

在这里插入图片描述
图形理解:
在这里插入图片描述
代码实现:

typedef int QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;
//队列初始化
void QueueInit(Queue* pq);
//队列销毁
void QueueDestroy(Queue* pq);
//入队列
void QueuePush(Queue* pq, QDataType x);
//出队列
void QueuePop(Queue* pq);
//队列大小
int QueueSize(Queue* pq);
//队列判空
bool QueueEmpty(Queue* pq);
//获取队头元素
QDataType QueueFront(Queue* pq);
//获取队尾元素
QDataType QueueBase(Queue* pq);

//队列初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
//队列销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
//入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("QueuePush::malloc");
		return;
	}
	newnode->next = NULL;
	newnode->data = x;
	if (pq->head == NULL)
	{
		assert(pq->tail == NULL);
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}
//出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	//QNode* del = pq->head;
	//pq->head = del->next;
	//free(del);
	//if (pq->head == NULL)
	//	pq->tail = NULL;
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}
//队列大小
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}
//队列判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}
//获取队头元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}
//获取队尾元素
QDataType QueueBase(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* pst=(MyStack*)malloc(sizeof(MyStack));
    if(pst==NULL)
    {
        perror("myStackCreate()::malloc");
        return NULL;
    }
    QueueInit(&pst->q1);
    QueueInit(&pst->q2);
    return pst;
}

void myStackPush(MyStack* obj, int x) {
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }
}

int myStackPop(MyStack* obj) {
    Queue* noneempty=&obj->q1;
    Queue* empty=&obj->q2;
    if(QueueEmpty(&obj->q1))
    {
        noneempty=&obj->q2;
        empty=&obj->q1;
    }
    while(QueueSize(noneempty)>1)
    {
        QueuePush(empty,QueueFront(noneempty));
        QueuePop(noneempty);
    }
    int top=QueueFront(noneempty);
    QueuePop(noneempty);
    return top;
}

int myStackTop(MyStack* obj) {
    if(!QueueEmpty(&obj->q1))
    {
       return QueueBase(&obj->q1);
    }
    else
    {
       return QueueBase(&obj->q2);
    }
}

bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(&obj->q1)&&
    QueueEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}

3.3用栈实现队列

在这里插入图片描述
图形理解:
在这里插入图片描述
代码实现:

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;//栈的容量
}ST;

//栈的初始化
void STackInit(ST* ps);
//栈的销毁
void STackDestroy(ST* ps);
//入栈
void STackPush(ST* ps, STDataType x);
//出栈
void STackPop(ST* ps);
//判断是否栈空
bool STackEmpty(ST* ps);
//栈的大小
int STackSize(ST* ps);
//获取栈顶元素
STDataType STackTop(ST* ps);
//栈的初始化
void STackInit(ST* ps)
{
	assert(ps);
	STDataType* tmp = (STDataType*)malloc(sizeof(STDataType) * 3);
	if (tmp == NULL)
	{
		perror("STackInit(ST* ps)::malloc");
		return;
	}
	ps->a = tmp;
	ps->capacity = 3;
	ps->top = 0;//指向栈顶元素下一个位置
	//ps->a = -1;//指向栈顶元素的位置
}
//栈的销毁
void STackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->capacity = ps->top = 0;
}
//入栈
void STackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, 
			sizeof(STDataType)*ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("STackPush::realloc");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top++] = x;
}
//出栈
void STackPop(ST* ps)
{
	assert(ps);
	assert(!STackEmpty(ps));
	ps->top--;
}
//判断是否栈空
bool STackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
//栈的大小
int STackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}
//获取栈顶元素
STDataType STackTop(ST* ps)
{
	assert(ps);
	assert(!STackEmpty(ps));
	return ps->a[ps->top-1];
}
typedef struct {
    ST pushst;
    ST popst;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    if(obj==NULL)
    {
        perror("myQueueCreate()::malloc");
        return NULL;
    }
    STackInit(&obj->pushst);
    STackInit(&obj->popst);
    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    STackPush(&obj->pushst,x);
}

int myQueuePeek(MyQueue* obj) {
    if(STackEmpty(&obj->popst))
    {
        while(!STackEmpty(&obj->pushst))
        {
            STackPush(&obj->popst,STackTop(&obj->pushst));
            STackPop(&obj->pushst);
        }
    }
    return STackTop(&obj->popst);
}

int myQueuePop(MyQueue* obj) {
    int top=myQueuePeek(obj);
    STackPop(&obj->popst);
    return top;
}


bool myQueueEmpty(MyQueue* obj) {
    return STackEmpty(&obj->pushst)&&
    STackEmpty(&obj->popst);
}

void myQueueFree(MyQueue* obj) {
    STackDestroy(&obj->pushst);
    STackDestroy(&obj->popst);
    free(obj);
}

3.4设计循环队列

在这里插入图片描述
代码实现:

typedef struct {
    int* a;
    int front;//首元素下标
    int rear;//末尾元素的下一个位置
    int k;//循环队列的数据个数
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    if(obj==NULL)
    {
        perror("myCircularQueueCreate::malloc");
        return NULL;
    }
    int* tmp=(int*)malloc(sizeof(int)*(k+1));//多开一段空间
    if(tmp==NULL)
    {
        perror("myCircularQueueCreate::malloc");
        return NULL;
    }
    obj->a=tmp;
    obj->front=obj->rear=0;
    obj->k=k;
    return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    //rear\front下标相同时,循环队列为空
    return obj->rear==obj->front;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    //rear下一个位置与front的位置相同时,循环队列为满
    return (obj->rear+1)%(obj->k+1)==obj->front;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
        //obj->a[obj->rear++]=value;
        obj->a[obj->rear++]=value;
        //rear到末尾的情况
        obj->rear %=(obj->k+1);
        return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    obj->front++;
    //front到末尾的情况
    obj->front%=(obj->k+1);
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->a[obj->front];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    else
    {
        //rear前一个的位置为队尾的情况
        //rear在数组开头的时候,特殊处理
        return obj->a[(obj->rear-1+obj->k+1)%(obj->k+1)];
    }
}
void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    free(obj);
}

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

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

相关文章

神级 IDEA 插件!效率提升 50 倍!

安装好Intellij idea之后&#xff0c;进行如下的初始化操作&#xff0c;工作效率提升50倍。 一. 安装插件 1. Codota 代码智能提示插件 只要打出首字母就能联想出一整条语句&#xff0c;这也太智能了&#xff0c;还显示了每条语句使用频率。原因是它学习了我的项目代码&#…

4.从CPU缓存结构到原子操作

一、CPU缓存结构 1.1 CPU的多级缓存 因为CPU的计算速度非常快&#xff0c;但内存的访问速度相对较慢。因此&#xff0c;如果CPU每次都要从内存读取数据&#xff0c;会造成大量的等待时间&#xff0c;降低整体性能。 通过引入多级缓存&#xff0c;可以在CPU和内存之间建立数据…

html5学习精选5篇案例

html5学习心得1 一&#xff1a;了解HTML5前端开发技术 HTML 指的是超文本标记语言 (Hyper Text Markup Language)&#xff0c;标记语言是一套标记标签 (markup tag)&#xff0c;HTML 使用标记标签来描述网页。HTML5区别于HTML的标准&#xff0c;基于全新的规则手册&#xff0…

stm32mp157aaa裸机开发学习之led灯亮灭

asm-led.S .text .global _start _start: /**********LED1点灯**********//**********RCC章节初始化**********/ RCC_INIT:通过RCC_MP_AHB4ENSETR寄存器使能GPIOE组控制器 0x50000A28[4] 1ldr r0,0x50000A28 LED1 GPIOE10 LED3 GPIOE8ldr r1,[r0]orr r1,r1,#(0x1 << 4…

vite4+vue3:从0到1搭建vben后台管理系统(四)-封装dayjs的日历组件

前言 在后台管理系统中,封装vue的日历组件是很常见的一个功能,有时候antdvue里面的组件跟我们业务需求差异比较大时,去改antdui的官方组件比较麻烦,这个时候,我们就得自己去封装这样一个日历组件,效果如下图所示: 两种实现方式之vue2.x的实现 <template><div&…

用简单易懂的方式手写一个单例模式,看了不会来打我

文章目录 一、如何手写一个单例模式1.1 什么是单例模式1.2 单例模式的适用场景1.3 单例模式的设计原理1.4 单例模式的实现方案1.5 代码测试 一、如何手写一个单例模式 1.1 什么是单例模式 单例模式是一种常用的软件设计模式&#xff0c;它的核心是只包含一个实例的特殊类。单…

每日一道算法题--进制转换

进制转换 题目来源解题思路代码 题目来源 题目链接: 进制转换 解题思路 首先&#xff0c;从标准输入读取两个整数 M 和 N&#xff0c;分别表示待转换的十进制数和目标进制。如果输入的十进制数 M 等于 0&#xff0c;直接输出 0 并返回。判断输入的十进制数是否为负数&#xf…

网络商城源码如何选择?

电商行业的不断发展&#xff0c;越来越多的企业和商家希望建设自己的网络商城系统&#xff0c;为消费者提供更加便捷的购物体验。 但是&#xff0c;想要实现这一目标&#xff0c;选择一款优秀的网络商城系统源码至关重要。那么&#xff0c;在如此众多的商城系统源码中&#xff…

局域网内,将笔记本作为台式机的扩展屏

目录 1、驱动端下载&#xff1a; 2、笔记本下载 显示端&#xff1a; 3、连接状态&#xff1a; 4、笔记本扩展屏&#xff1a; 如果&#xff0c;都支持无线显示器的话&#xff0c;可以用window内置的winp实现&#xff0c;可惜我的台式机不支持&#xff0c;所以采用了软件的方…

结构体和数据结构--向函数传递结构体

将结构体传给函数的方式有以下三种&#xff1a; 目录 一、用结构体的单个成员作为函数参数&#xff0c;向函数传递结构体的单个成员 二、用结构体变量作函数实参&#xff0c;向函数传递结构体得完整结构 三、用结构体指针或结构体数组作函数参数&#xff0c;向函数传递结构体…

亿发软件:智能制造时代,企业为什么选择量身定制信息化软件系统

在快节奏的市场环境中&#xff0c;每个企业都寻求建立自己的管理模式&#xff0c;这往往成为竞争优势。然而&#xff0c;标准化软件产品的使用有时会扼杀企业管理的个性化&#xff0c;而僵化的制度则阻碍管理升级。此外&#xff0c;单个的部门级软件会造成信息孤岛&#xff0c;…

【电子量产工具】2.输入系统

文章目录 前言一、输入系统分析二、封装输入结构体三、底层 touchscreen四、底层 netinput五、显示管理层六、测试程序测试效果 总结 前言 最近看了 电子量产工具 这个项目&#xff0c;本专栏是对该项目的一个总结。 对于输入系统&#xff0c;这里只介绍 触摸屏线程 和 网络线…

7-WebApis-6

Web APIs - 6 目标&#xff1a;能够利用正则表达式完成小兔鲜注册页面的表单验证&#xff0c;具备常见的表单验证能力 正则表达式综合案例阶段案例 正则表达式 正则表达式&#xff08;Regular Expression是一种字符串匹配的模式&#xff08;规则&#xff09; 使用场景&#…

微信小程序申请

方案说明&#xff1a; 微信小程序申请步骤有两个过程&#xff0c;目前采用的是第二种方案 第一种方案&#xff1a;直接向微信申请微信小程序 第二种方案&#xff1a;先申请公众号后再通过公众号快速注册并申请小程序 无论申请公众号还是小程序都需要微信认证&#xff0c;微…

ubuntu18.04下安装PCL

整体步骤可参考&#xff1a;https://blog.csdn.net/qq_42257666/article/details/124574029 在本人安装过程中&#xff0c;遇到一些问题&#xff0c;做几点说明&#xff1a; 1.在配置VTK的过程中报错如下&#xff1a; 解决方法&#xff1a; sudo apt install libqt5x11extras…

Nginx【Nginx核心指令(rewrite指令、实战rewrite 、if指令、set和break指令】(六)-全面详解(学习总结---从入门到深化)

目录 Nginx核心指令_rewrite指令 Nginx核心指令_实战rewrite Nginx核心指令_if指令 Nginx核心指令_set和break指令 Nginx核心指令_rewrite指令 地址重写与地址转发 地址重写 地址重写是实际上是为了实现址标准化&#xff0c;就像访问www.baidu.cn可 以出现www.baidu.com的…

阿里云企业邮箱标准版用户数功能说明

阿里云企业邮箱标准版不同用户数费用表&#xff0c;标准版企业邮箱不限制账号容量、20GB共享网盘容量、5GB个人网盘容量&#xff0c;默认5个账号数540元一年&#xff0c;原价是600元一年&#xff0c;年付9折、多年付8折&#xff0c;阿里云百科分享企业邮箱标准版不同账号数收费…

软件测试技能,JMeter压力测试教程,请求body自动签名带上sign参数(二十一)

一、前言 接口请求body带有sign签名参数&#xff0c;sign签名是根据请求body除去sign本身参数后&#xff0c;拼接请求参数最后md5加密生成的 使用 jmeter 测试接口&#xff0c;我们希望在请求之前修改 post body 里面的 sign 参数的值为签名的值 二、sign签名 签名一篇的实…

Alibaba Sentinel | 熔断规则详解

文章目录 简介熔断策略-慢调用比例结论&#xff1a;流程图&#xff1a;熔断结果详细解释 熔断策略-异常比例结论&#xff1a;详细解释 熔断策略-异常数结论&#xff1a;详细解释 统计异常数、比例的方法编码加注解RuntimeException 总结 简介 熔断是一种保护机制&#xff0c;用…

Redis持久化(RDB、AOF)

Redis持久化&#xff08;RDB、AOF&#xff09; 一、Redis高可用二、Redis持久化三、Redis的RDB持久化1、触发条件1.1 手动触发1.2 自动触发1.3 其它自动触发机制 2、执行流程3、启动时加载RED文件(恢复) 四、Redis的AOF持久化1、开启AOF2、执行流程2.1 命令追加&#xff08;app…