当前位置: 首页 > news >正文

【c语言】简单贪吃蛇的实现

目录

一、游戏说明

​编辑

二、地图坐标​

​编辑

三、头文件

四、蛇身和食物​

五、数据结构设计​

蛇节点结构如下:

封装一个Snake的结构来维护整条贪吃蛇:​

蛇的方向,可以一一列举,使用枚举:

游戏状态,可以一一列举,使用枚举:

六、Snake.c

5.1、游戏开始函数

定位控制台的光标位置

欢迎来到贪吃蛇游戏

创建一个地图

初始化创建蛇身的节点

创建第一个食物​

5.2、游戏运行函数

检测按键状态,我们封装了一个宏

打印帮助信息

暂停函数

下一个是否是食物

下一步要走的位置处就是食物,就吃掉食物

如果下一步不是食物

检测是否撞墙

检测是否撞自己

蛇移动的函数

七、游戏结束的资源释放

八、Test.c


一、游戏说明

  • 贪吃蛇地图绘制
  • 蛇吃食物的功能 (上、下、左、右方向键控制蛇的动作)​
  • 蛇撞墙死亡
  • 蛇撞自身死亡
  • 计算得分
  • 蛇身加速、减速
  • 暂停游戏

二、地图坐标​

我们假设实现一个棋盘27行,58列的棋盘(行和列可以根据自己的情况修改),再围绕地图画出墙,如下:

三、头文件

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<stdbool.h>
#include<locale.h>#define Case break;case#define WALL L'□'
#define BODY L'●'
#define FOOD L'☆'//默认的起始坐标
#define POS_X 24
#define POS_Y 5#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )//贪吃蛇,蛇身节点的定义
typedef struct SnakeNode
{int x;int y;struct SnakeNode* next;
}SnakeNode, * pSnakeNode;
//typedef struct SnakeNode* pSnakeNode;enum GAME_STATUS//游戏状态
{OK = 1,//正常运行ESC,//按了ESC键退出,正常退出KILL_BY_WALL,//撞墙KILL_BY_SELF//撞到自身
};//行走的方向
enum DIRECTION//方向
{UP = 1,DOWN,LEFT,RIGHT
};//贪吃蛇
typedef struct Snake
{pSnakeNode pSnake;//维护整条蛇的指针,是指向蛇头pSnakeNode pFood;//指向食物的指针int Score;//当前累积的分数int FoodWeight;//一个食物的分数,默认每个食物10分int SleepTime;//每走一步休眠时间?//蛇休眠的时间,休眠的时间越短,蛇的速度越快,休眠的时间越长,蛇的速度越慢enum GAME_STATUS status;//游戏当前的状态enum DIRECTION dir;//蛇当前走的方向,蛇头的方向默认是向右//...
}Snake,* pSnake;
//typedef struct Snake* pSnake;//定位控制台的光标位置
void SetPos(int x, int y);//游戏开始的准备
void GameStart(pSnake ps);//打印欢迎界面
void welcomeToGame();//绘制地图
void CreateMap();//初始化蛇
void InitSnake(pSnake ps);//创建食物
void CreateFood(pSnake ps);//游戏运行的整个逻辑
void GameRun(pSnake ps);//打印帮助信息
void PrintHelpInfo();//蛇移动的函数- 每次走一步
void SnakeMove(pSnake ps);//判断蛇头的下一步要走的位置处是否是食物
int NextIsFood(pSnake ps, pSnakeNode pNext);//下一步要走的位置处就是食物,就吃掉食物
void EatFood(pSnake ps, pSnakeNode pNext);//下一步要走的位置处不是食物,不吃食物
void NotEatFood(pSnake ps, pSnakeNode pNext);//检测是否撞墙
void KillByWall(pSnake ps);//检测是否撞自己
void KillBySelf(pSnake ps);//游戏结束的资源释放
void GameEnd(pSnake ps);

四、蛇身和食物​

初始化状态,假设蛇的长度是5,蛇身的每个节点是●,在固定的一个坐标处,比如(24, 5)处开始出现蛇,连续5个节点。

注意:蛇的每个节点的x坐标必须是2个倍数,否则可能会出现蛇的一个节点有一半儿出现在墙体中,另外一般在墙外的现象,坐标不好对齐。
关于食物,就是在墙体内随机生成一个坐标(x坐标必须是2的倍数),坐标不能和蛇的身体重合,然后打印★。

五、数据结构设计​

在游戏运行的过程中,蛇每次吃一个食物,蛇的身体就会变长一节,如果我们使用链表存储蛇的信
息,那么蛇的每一节其实就是链表的每个节点。每个节点只要记录好蛇身节点在地图上的坐标就行。

#define WALL L'□'  墙
#define BODY L'●'  蛇身
#define FOOD L'☆' 食物

蛇节点结构如下:

//贪吃蛇,蛇身节点的定义
typedef struct SnakeNode
{int x;int y;struct SnakeNode* next;//是一个指向下一个 SnakeNode 类型节点的指针,用于构建链表来表示蛇的身体。
}SnakeNode, * pSnakeNode;
//typedef struct SnakeNode* pSnakeNode;

封装一个Snake的结构来维护整条贪吃蛇:​

pSnakeNode pSnake:这是一个指向 SnakeNode 类型的指针,代表蛇的头部。通常,贪吃蛇的实现会用一个链表来表示蛇的身体,其中每个节点(SnakeNode)代表蛇身体的一部分,而 pSnake 指向这个链表的第一个节点,即蛇头。

pSnakeNode pFood:这是一个指向 SnakeNode 类型的指针,代表食物的位置。在贪吃蛇游戏中,食物会被随机放置在游戏区域内,当蛇吃到食物时,这个食物会被移除,并且蛇的身体会增长。

enum GAME_STATUS status;:这是一个枚举类型,表示游戏当前的状态。具体的枚举值没有在代码中给出,但可能包括“游戏中”、“游戏结束”等状态。

enum DIRECTION dir;:这是一个枚举类型,表示蛇当前移动的方向。具体的枚举值也没有在代码中给出,但通常包括“向上”、“向下”、“向左”、“向右”等方向。

typedef struct Snake
{pSnakeNode pSnake;//维护整条蛇的指针,是指向蛇头pSnakeNode pFood;//指向食物的指针int Score;//当前累积的分数int FoodWeight;//一个食物的分数,默认每个食物10分int SleepTime;//每走一步休眠时间?//蛇休眠的时间,休眠的时间越短,蛇的速度越快,休眠的时间越长,蛇的速度越慢enum GAME_STATUS status;//游戏当前的状态enum DIRECTION dir;//蛇当前走的方向,蛇头的方向默认是向右//...
}Snake,* pSnake;
//typedef struct Snake* pSnake;

蛇的方向,可以一一列举,使用枚举:

//行走的方向
enum DIRECTION//方向
{UP = 1,DOWN,LEAF,RIGHT
};

游戏状态,可以一一列举,使用枚举:

enum GAME_STATUS//游戏状态
{OK = 1,//正常运行ESC,//按了ESC键退出,正常退出KILL_BY_WALL,//撞墙KILL_BY_SELF//撞到自身
};

六、Snake.c

5.1、游戏开始函数

void GameStart(pSnake ps)
{//设置控制台的信息,窗口大小,窗口名system("mode con cols=120 lines=40");system("title 贪吃蛇");//隐藏光标HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false;SetConsoleCursorInfo(handle, &CursorInfo);//设置光标信息//打印欢迎信息welcomeToGame();//绘制地图CreateMap();//初始化蛇InitSnake(ps);//创建食物CreateFood(ps);}

定位控制台的光标位置

//定位控制台的光标位置
void SetPos(int x, int y)
{//获得设备句柄HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//根据句柄设置光标的位置COORD pos = { x,y };SetConsoleCursorPosition(handle, pos);
}

欢迎来到贪吃蛇游戏

void welcomeToGame()
{//欢迎信息SetPos(35, 10);printf("欢迎来到贪吃蛇小游戏\n");SetPos(38, 20);system("pause");system("cls");//功能介绍信息SetPos(15, 10);printf("用 ↑ . ↓ . ← . → 来控制蛇的移动,F3是加速,F4是减速\n");SetPos(15, 11);printf("加速能得到更高的分数");SetPos(38, 20);system("pause");system("cls");}

创建一个地图

创建地图就是将墙打印出来,因为是宽字符打印,所有使用wprintf函数,打印格式串前使用L​
打印地图的关键是要算好坐标,才能在想要的位置打印墙体。

void CreateMap()
{int i = 0;//上SetPos(0, 0);for (i = 0; i <= 56; i += 2){wprintf(L"%lc", WALL);}//下SetPos(0, 25);for (i = 0; i <= 56; i += 2){wprintf(L"%lc", WALL);}//左for (i = 1; i <= 25; i++){SetPos(0, i);wprintf(L"%lc", WALL);}//右for (i = 1; i <= 25; i++){SetPos(56, i);wprintf(L"%lc", WALL);}
}

初始化创建蛇身的节点

蛇最开始长度为5节,每节对应链表的一个节点,蛇身的每一个节点都有自己的坐标。​
创建5个节点,然后将每个节点存放在链表中进行管理。创建完蛇身后,将蛇的每一节打印在屏幕上。再设置当前游戏的状态,蛇移动的速度,默认的方向,初始成绩,蛇的状态,每个食物的分数。

结构体成员:记录它们的坐标:(x,y),和记录下一个位置的前驱结构体指针:next。

void InitSnake(pSnake ps)
{//创建五个蛇身的节点pSnakeNode cur = NULL;int i = 0;for (i = 0; i < 5; ++i){cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("InsitSnkae():malloc()");return;}cur->x = POS_X + 2 * i;cur->y = POS_Y;cur->next = NULL;//头插法if (ps->pSnake == NULL){ps->pSnake = cur;}else {cur->next = ps->pSnake;ps->pSnake = cur;}}//打印蛇身cur = ps->pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//贪吃蛇的其他信息ps->dir = RIGHT;ps->FoodWeight = 10;ps->pFood = NULL;ps->Score = 0;ps->SleepTime = 200;ps->status = OK;}

创建第一个食物​

  • 先随机生成食物的坐标
  • x坐标必须是2的倍数​
  • 食物的坐标不能和蛇身每个节点的坐标重复
  • 创建食物节点,打印食物
void CreateFood(pSnake ps)
{int x = 0;//x范围: 2~54 -> 0~52 + 2 -> rand()%53 + 2int y = 0;//y范围: 1~25 -> 0~24 + 1 -> rand()%24 + 1again:do {x = rand() % 53 + 2;y = rand() % 24 + 1;} while (x % 2 != 0);//坐标和蛇的身体的每个几点的坐标比较pSnakeNode cur = ps->pSnake;while (cur){if (x == cur->x && y == cur->y){goto again;}cur = cur->next;}//创建食物pSnakeNode pFood = malloc(sizeof(SnakeNode));if (pFood == NULL){perror("CreateFood:malloc()");return;}pFood->x = x;pFood->y = y;ps->pFood = pFood;SetPos(x, y);wprintf(L"%lc", FOOD);}

5.2、游戏运行函数

游戏运行期间,右侧打印帮助信息,提示玩家
根据游戏状态检查游戏是否继续,如果是状态是OK,游戏继续,否则游戏结束。​
如果游戏继续,就是检测按键情况,确定蛇下一步的方向,或者是否加速减速,是否暂停或者退出游戏。
确定了蛇的方向和速度,蛇就可以移动了。

void GameRun(pSnake ps)
{//打印帮助信息PrintHelpInfo();//检测按键do{//当前的分数情况SetPos(62, 10);printf("总分:%5d\n", ps->Score);SetPos(62, 11);printf("食物的分支:%02d\n", ps->FoodWeight);//检测按键//上、下、左、右、ESC、空格、F3、F4if (KEY_PRESS(VK_UP) && ps->dir != DOWN){ps->dir = UP;}else if (KEY_PRESS(VK_DOWN) && ps->dir != UP){ps->dir = DOWN;}else if (KEY_PRESS(VK_LEFT) && ps->dir != RIGHT){ps->dir = LEFT;}else if (KEY_PRESS(VK_RIGHT) && ps->dir != LEFT){ps->dir = RIGHT;}else if (KEY_PRESS(VK_ESCAPE)){ps->status = ESC;break;}else if (KEY_PRESS(VK_SPACE)){//游戏要暂停pause();//暂停和开始} else if (KEY_PRESS(VK_F3)){if (ps->SleepTime >= 80){ps->SleepTime -= 30;ps->FoodWeight += 2;}}else if (KEY_PRESS(VK_F4)){if (ps->FoodWeight > 2){ps->SleepTime += 30;ps->FoodWeight -= 2;}}//走一步SnakeMove(ps);//睡眠一下Sleep(ps->SleepTime);}while(ps->status == OK);}

检测按键状态,我们封装了一个宏

#define KEY_PRESS(VK) ((GetAsyncKeyState(VK)&0x1) ? 1 : 0)

打印帮助信息

//打印帮助信息
void PrintHelpInfo()
{SetPos(62, 15);printf("1. 不能穿墙. 不能咬到自己");SetPos(62, 16);printf("2. 用 ↑ . ↓ . ← . → 来控制蛇的移动");SetPos(62, 17);printf("3. F3是加速,F4是减速");SetPos(62, 19);printf(" ");}

暂停函数

void pause()
{while (1){Sleep(100);if (KEY_PRESS(VK_SPACE)){break;}}
}

下一个是否是食物

//pSnakeNode psn 是下一个节点的地址​
//pSnake ps 维护蛇的指针
int NextIsFood(pSnake ps, pSnakeNode pNext)
{if (ps->pFood->x == pNext->x && ps->pFood->y == pNext->y)return 1;elsereturn 0;
}

下一步要走的位置处就是食物,就吃掉食物

//下一步要走的位置处就是食物,就吃掉食物
void EatFood(pSnake ps, pSnakeNode pNext)
{pNext->next = ps->pSnake;ps->pSnake = pNext;pSnakeNode cur = ps->pSnake;//打印蛇身while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->Score += ps->FoodWeight;//释放旧的食物free(ps->pFood);//新建食物CreateFood(ps);
}

如果下一步不是食物

将下一个节点头插入蛇的身体,并将之前蛇身最后一个节点打印为空格,放弃掉蛇身的最后一个节点

//pSnakeNode psn 是下一个节点的地址​
//pSnake ps 维护蛇的指针​
void NotEatFood(pSnake ps, pSnakeNode pNext)
{//头插法pNext->next = ps->pSnake;ps->pSnake = pNext;//释放尾结点pSnakeNode cur = ps->pSnake;while (cur->next->next){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//将尾节点的位置打印成空白字符SetPos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;//易错
}

检测是否撞墙

判断蛇头的坐标是否和墙的坐标冲突

//检测是否撞墙
void KillByWall(pSnake ps)
{if (ps->pSnake->x == 0 ||ps->pSnake->x == 56 ||ps->pSnake->y == 0 ||ps->pSnake->y == 25){ps->status = KILL_BY_WALL;}}

检测是否撞自己

判断蛇头的坐标是否和蛇身体的坐标冲突

//检测是否撞自己
void KillBySelf(pSnake ps)
{pSnakeNode cur = ps->pSnake->next;//从第二个节点开始while (cur){if (cur->x == ps->pSnake->x && cur->y == ps->pSnake->y){ps->status = KILL_BY_SELF;return;}cur = cur->next;}
}

蛇移动的函数

先创建下一个节点,根据移动方向和蛇头的坐标,蛇移动到下一个位置的坐标。
确定了下一个位置后,看下一个位置是否是食物(NextIsFood),是食物就做吃食物处理
(EatFood),如果不是食物则做前进一步的处理(NoFood)。​
蛇身移动后,判断此次移动是否会造成撞墙(KillByWall)或者撞上自己蛇身(KillBySelf),从而影响游戏的状态。

void SnakeMove(pSnake ps)
{pSnakeNode pNext = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNext == NULL){perror("SnakeMove():malloc()");return;}pNext->next = NULL;switch (ps->dir){case UP:pNext->x = ps->pSnake->x;pNext->y = ps->pSnake->y - 1;break;Case DOWN:pNext->x = ps->pSnake->x;pNext->y = ps->pSnake->y + 1;Case LEFT:pNext->x = ps->pSnake->x - 2;pNext->y = ps->pSnake->y;Case RIGHT:pNext->x = ps->pSnake->x + 2;pNext->y = ps->pSnake->y;break;}//下一个坐标是否是食物if (NextIsFood(ps, pNext)){//是食物就吃掉EatFood(ps, pNext);}else {//不是食物就正常一步NotEatFood(ps, pNext);}//检测撞墙KillByWall(ps);//检测是否撞自己KillBySelf(ps);}

七、游戏结束的资源释放

游戏状态不再是OK(游戏继续)的时候,要告知游戏结束的原因,并且释放蛇身节点。​

//游戏结束的资源释放
void GameEnd(pSnake ps)
{SetPos(20, 15);switch (ps->status){case ESC:printf("主动退出游戏,正常退出\n");Case KILL_BY_WALL:printf("很遗憾,撞墙了,游戏结束\n");Case KILL_BY_SELF:printf("很遗憾,撞到自己了,游戏结束\n");break;}//释放贪吃蛇的链表资源pSnakeNode cur = ps->pSnake;pSnakeNode del = NULL;while (cur){del = cur;cur = cur->next;free(del);}free(ps->pFood);ps = NULL;
}

八、Test.c

void test()
{//创建贪食蛇Snake snake = { 0 };//GameStart(&snake);//游戏开始前的初始化//GameRun();//玩游戏的过程//GameEnd();//善后的工作int ch = 0;do{Snake snake = { 0 };GameStart(&snake);//游戏开始前的初始化GameRun(&snake);//玩游戏的过程GameEnd(&snake);//善后的工作SetPos(15, 20);printf("再来一局吗?(Y/N):");ch = getchar();getchar();// 清理\n} while (ch == 'Y' || ch == 'y');
}int main()
{//修改适配本地的环境setlocale(LC_ALL, "");test();//贪吃蛇游戏的测试SetPos(0, 30);return 0;
}

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

相关文章:

【c语言】简单贪吃蛇的实现

目录 一、游戏说明 ​编辑 二、地图坐标​ ​编辑 三、头文件 四、蛇身和食物​ 五、数据结构设计​ 蛇节点结构如下&#xff1a; 封装一个Snake的结构来维护整条贪吃蛇&#xff1a;​ 蛇的方向&#xff0c;可以一一列举&#xff0c;使用枚举&#xff1a; 游戏状态&a…...

2023年09月CCF-GESP编程能力等级认证Python编程六级真题解析

Python等级认证GESP(1~6级)全部真题・点这里 一、单选题(共15题,共30分) 第1题 近年来,线上授课变得普遍,很多有助于改善教学效果的设备也逐渐流行,其中包括比较常用的手写板,那么它属于哪类设备?( ) A:输入 B:输出 C:控制 D:记录 答案:A 第2题 以下关于…...

Flink中StateBackend(工作状态)与Checkpoint(状态快照)的关系

State Backends 由 Flink 管理的 keyed state 是一种分片的键/值存储&#xff0c;每个 keyed state 的工作副本都保存在负责该键的 taskmanager 本地中。另外&#xff0c;Operator state 也保存在机器节点本地。Flink 定期获取所有状态的快照&#xff0c;并将这些快照复制到持…...

【C语言刷题系列】喝汽水问题

文章目录 一、文章简介 1.先买再换 1.1 代码逻辑&#xff1a; 1.2 完整代码 1.3 运行结果 1.4 根据方法一总结优化 2.边买边换 2.1 代码逻辑&#xff1a; 2.2 完整代码 2.3 运行结果 一、文章简介 本文所述专栏——C语言经典编程问题 C语言刷题_倔强的石头106的博客…...

[C++] C++ 11的functional模块介绍和使用案例

functional模块介绍 functional模块是C 11提供了一组函数对象和算法&#xff0c;用于增强C的函数式编程能力。该模块中的函数对象和算法可以大大简化代码&#xff0c;并提供了一些有用的工具&#xff0c;例如函数适配器和函数对象的组合。 functional模块中的函数对象包括&am…...

kubernetes基本概念和操作

基本概念和操作 1.Namespace1.1概述1.2应用示例 2.Pod2.1概述2.2语法及应用示例 3.Label3.1概述3.2语法及应用示例 4.Deployment4.1概述4.2语法及应用示例 5.Service5.1概述5.2语法及应用示例5.2.1创建集群内部可访问的Service5.2.2创建集群外部可访问的Service5.2.3删除服务5.…...

20240128周报-网络太杂,Tomcat太难

今天来做个小总结吧&#xff0c;之前说想用几个月的时间将Java生态给整理一遍&#xff0c;该工作已经进入第三周了。先和各位老老板汇报一下上一周的工作&#xff0c;然后说一下本周的计划和后面的计划。 1.上周工作 上周的计划是将网络和Tomcat的内容梳理一番&#xff0c;但…...

DES加密原理

DES加密算法综合运用了置换、代替、代数等多种密码技术&#xff0c;具有设计精 巧、实现容易、使用方便等特点。DES加密算法的明文、密文和密钥的分组长度 都是64位&#xff0c;详细的DES加密算法结构如图6-10所示。 图6-10 DES加密算法结构图 DES加密过程如下所示&#xff…...

react 之 useCallback

简单讲述下useCallback的使用方法&#xff0c;useCallback也是用来缓存的&#xff0c;只不过是用于做函数缓存 // useCallbackimport { memo, useCallback, useState } from "react"const Input memo(function Input ({ onChange }) {console.log(子组件重新渲染了…...

OfficeWeb365 Readfile 任意文件读取漏洞复现

0x01 产品简介 OfficeWeb365 是专注于 Office 文档在线预览及PDF文档在线预览云服务,包括 Microsoft Word 文档在线预览、Excel 表格在线预览、Powerpoint 演示文档在线预览,WPS 文字处理、WPS 表格、WPS 演示及 Adobe PDF 文档在线预览。 0x02 漏洞概述 OfficeWeb365 Rea…...

UnityShader(十三)Unity内置的函数

在计算光照模型时我们需要得到许多数据&#xff0c;比如光源方向、视角方向这种基本信息。 在之前的例子中都是自行在代码里计算的&#xff0c;比如&#xff1a; normalize(_WorldSpaceLight0Pos.xyz) 得到光源方向&#xff08;这种方法实际只适用平行光&#xff09; normaliz…...

【开源】基于Qt5的ROS1/ROS2人机交互软件(支持地图编辑/多点导航)

本项目基于Qt5开发&#xff0c;基于CMake进行构建&#xff0c;可以实现一套代码同时在ROS1/ROS2系统中使用(本项目已接入CI,保证多ROS版本/系统版本可用性) 项目地址&#xff1a; https://github.com/chengyangkj/Ros_Qt5_Gui_App 软件在编译时会自动识别环境变量中的ROS1/ROS…...

Spring和SpringBoot的区别是什么

Spring 和 Spring Boot 是 Java 开发领域内两个极其重要且紧密相关的框架&#xff0c;它们各自在企业级应用开发中扮演着不同的角色&#xff0c;并带来了一系列革新性的变化。以下是关于两者之间主要区别的详细分析&#xff1a; 一、设计理念与定位 Spring Framework Spring 是…...

布局技巧及CSS初始化

一&#xff0c;margin负值巧妙应用 二&#xff0c;文字围绕浮动元素 三&#xff0c;行内块 四&#xff0c;CSS三角强化 五&#xff0c;CSS初始化 一&#xff0c;margin负值巧妙应用 制作盒子的细线边框&#xff1a; 鼠标经过li后变色&#xff1a; 二&#xff0c;文字围绕…...

excel怎么设置密码?轻松保护您的工作表

在数字化时代&#xff0c;数据的安全性显得尤为重要。excel作为我们日常工作中广泛使用的办公软件&#xff0c;其中可能包含了大量的敏感数据。为了确保这些数据不被未授权的人访问&#xff0c;本文将为您详细介绍excel怎么设置密码&#xff0c;从而有效地保护您的数据安全。 方…...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TimePicker组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之TimePicker组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、TimePicker组件 TextClock组件通过文本将当前系统时间显示在设备上。支持不…...

Springboot集成Camunda并完成一条流程实例

&#x1f496;专栏简介 ✔️本专栏将从Camunda(卡蒙达) 7中的关键概念到实现中国式工作流相关功能。 ✔️文章中只包含演示核心代码及测试数据&#xff0c;完整代码可查看作者的开源项目snail-camunda ✔️请给snail-camunda 点颗星吧&#x1f618; &#x1f496;设计流程定…...

宠物用品/宠物自动饮水机方案

宠物自动饮水机方案原理 宠物自动饮水机&#xff0c;也叫做智能宠物饮水机&#xff0c;是一种为宠物设计的智能化饮水器。应用核心主要在于智能化水泵控制&#xff0c;以及外围传感器电路。 宠物自动饮水机使用方便&#xff0c;不用频繁的换水。另外&#xff0c;自来水的水质可…...

git小白进阶之路

git是最常用的版本控制工具&#xff0c;我对其进行了整理后续补充&#xff0c;这个文档欢迎大家来讨论&#xff0c;当前我的视频梳理&#xff1a; git小白进阶之路_哔哩哔哩_bilibili&#xff0c;非常希望大佬们能够批评指正&#xff0c;并多多交流。 目录 初始配置 配置账号…...

哈希表——C++

目录 一、首先使用拉链法&#xff1a; 二、开放寻址法 三、字符串哈希 1.具体如何使用进制的方式来存储字符前缀的可以看这个y总的这个图 2.接下来说一说算某个中间的区间的字符串哈希值 哈希表是一种数组之间互相映射的数据结构&#xff0c;比如举个简单的例子一个十个的数…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...