贪吃蛇——c语言版

文章目录

  • 演示效果
  • 实现的基本功能
  • 技术要点
  • 源代码
  • 实现功能
    • GameStart
      • 打印欢迎界面和功能介绍
      • 绘制地图
      • 创建蛇
      • 创建食物
    • GameRun
      • 打印提示信息
      • 蛇每走一步
    • GameEnd
    • 蛇死亡后继续游戏

演示效果

贪吃蛇1.0演示视频


在这里插入图片描述
将终端应用程序改为控制台主机

实现的基本功能

  1. 贪吃蛇地图绘制
  2. 蛇吃食物的功能(上、下、左、右⽅向键控制蛇的动作)
  3. 蛇撞墙死亡
  4. 蛇撞⾃⾝死亡
  5. 计算得分
  6. 蛇⾝加速、减速
  7. 暂停游戏

技术要点

c语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等等……

源代码

snake.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <locale.h>
#include <stdbool.h>
#include <time.h>
#include <stdbool.h>
#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)
#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'
#define POS_X 24
#define POS_Y 5
enum DIRECTION
{UP = 1,DOWN,LEFT,RIGHT
};
enum CONDITION
{ OK,KILL_BY_WALL,KILL_BY_SELF,END_NORMAL
};
typedef struct SnakeNode
{int x;int y;struct SnakeNode* next;
}SnakeNode,* pSnakeNode;
typedef struct Snake
{pSnakeNode pSnakebody;//指向蛇头的节点pSnakeNode pFood;//指向食物的节点enum DIRECTION Dir;//方向enum CONDITION Cdt;//状态int Food_Weight;//食物的权重int Socre;//总分数int Sleep_Time;//睡眠时间
}Snake,* pSnake;
//初始化
void GameStart(pSnake ps);
//定位
void SetPos(short x, short y);
//打印欢迎界面和功能介绍
void  Welcome_To_Game();
//绘制地图
void CreateMap();
//创建蛇
void InitSnake(pSnake ps);
//创建食物
void CreateFood(pSnake ps);
//运行游戏
void GameRun(pSnake ps);
//打印提示信息
void PrintHelpInfo();
//蛇走的过程
void SnakeMove(pSnake ps);
//判断下一个节点是不是食物
bool NextIsFood(pSnakeNode pn,pSnake ps);
//如果是食物,就吃掉,然后创建新的食物
void EatFood(pSnakeNode pn,pSnake ps);
//如果不是食物,就把最后一个节点释放
void NotFood(pSnakeNode pn, pSnake ps);
//判断下一步是否撞墙
void KillByWall(pSnake ps);
//判断下一步是否撞到自己
void KillBySelf(pSnake ps);
//善后工作
void GameEnd(pSnake ps);

snake.c

#define   _CRT_SECURE_NO_WARNINGS 1
#include "Snake.h"
void CreateFood(pSnake ps)
{int x = 0;int y = 0;//食物的坐标在棋盘内
again:do{x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 != 0);//食物不能和蛇身冲突pSnakeNode cur = ps->pSnakebody;while (cur){if (cur->x == x && cur->y == y){goto again;}cur = cur->next;}//创建食物pSnakeNode Food = (pSnakeNode)malloc(sizeof(SnakeNode));if (Food == NULL){perror("malloc fail");return;}Food->next = NULL;Food->x = x;Food->y = y;SetPos(x, y);wprintf(L"%lc", FOOD);ps->pFood = Food;
}
void SetPos(short x, short y)
{HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x,y };SetConsoleCursorPosition(houtput, pos);
}
void InitSnake(pSnake ps)
{ps->pSnakebody = NULL;pSnakeNode cur = NULL;for (int i = 0; i < 5; i++){//创建蛇身节点cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("malloc fail");return;}//设置坐标cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;//头插if (ps->pSnakebody == NULL){ps->pSnakebody = cur;}else{cur->next = ps->pSnakebody;ps->pSnakebody = cur;}}//打印身体cur = ps->pSnakebody;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//初始化贪吃蛇的数据ps->Cdt = OK;ps->Dir = RIGHT;ps->Food_Weight = 10;ps->Socre = 0;ps->Sleep_Time = 200;//单位毫秒
}void CreateMap()
{int i = 0;//上for (i = 0; i < 29; i++){wprintf(L"%lc", WALL);}//下SetPos(0, 26);for (i = 0; i < 29; i++){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);}}void Welcome_To_Game()
{SetPos(40, 14);printf("欢迎来到贪食蛇小游戏");SetPos(40, 25);system("pause");system("cls");SetPos(25, 14);printf("用↑ . ↓ . ← . → 分别控制蛇的移动,F1为加速,");SetPos(25, 15);printf("F2为减速,加速将得到更高的分数");SetPos(40, 24);system("pause");system("cls");
}
void GameStart(pSnake ps)
{system("mode con cols=100 lines=30");system("title 贪吃蛇");//获取标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定义光标信息结构体CONSOLE_CURSOR_INFO CursorInfo;//获取光标信息GetConsoleCursorInfo(houtput, &CursorInfo);//修改CursorInfo.bVisible = false;//设置SetConsoleCursorInfo(houtput, &CursorInfo);//打印欢迎界面和功能介绍Welcome_To_Game();//绘制地图CreateMap();//创建蛇InitSnake(ps);//创建食物CreateFood(ps);
}
//打印提示信息
void PrintHelpInfo()
{SetPos(60, 15);printf("不能穿墙,不能咬到自己");SetPos(60, 16);printf("用 ↑.↓.←.→ 分别控制蛇的移动,");SetPos(60, 17);printf("F1为加速,F2为减速,加速将得到更高的分数");SetPos(60, 18);printf("ESC:退出游戏,SPACE:暂停游戏");SetPos(60, 20);printf("我爱吃福鼎肉片@版权");
}
//暂停
void pause()
{while (1){Sleep(300);if (KEY_PRESS(VK_SPACE)){break;}}
}
//判断下一个节点是不是食物
bool NextIsFood(pSnakeNode pn, pSnake ps)
{return (pn->x == ps->pFood->x && pn->y == ps->pFood->y);
}
//如果是食物,就吃掉,然后创建新的食物
void EatFood(pSnakeNode pn, pSnake ps)
{//头插ps->pFood->next = ps->pSnakebody;ps->pSnakebody = ps->pFood;//释放下一个位置的节点free(pn);pn = NULL;//打印pSnakeNode cur = ps->pSnakebody;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->Socre += ps->Food_Weight;CreateFood(ps);
}
//如果不是食物,就把最后一个节点释放
void NotFood(pSnakeNode pn, pSnake ps)
{//头插pn->next = ps->pSnakebody;ps->pSnakebody = pn;//最后一个节点,要释放pSnakeNode cur = ps->pSnakebody;while (cur->next->next)//打印前n个{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->pSnakebody->x == 56|| ps->pSnakebody->x == 0|| ps->pSnakebody->y == 0|| ps->pSnakebody->y == 26){ps->Cdt = KILL_BY_WALL;}
}
//判断下一步是否撞到自己
void KillBySelf(pSnake ps)
{pSnakeNode cur = ps->pSnakebody->next;while (cur){if (cur->x == ps->pSnakebody->x && cur->y == ps->pSnakebody->y){ps->Cdt = KILL_BY_SELF;}cur = cur->next;}
}
//蛇走的过程
void SnakeMove(pSnake ps)
{//创建下一个节点pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNextNode == NULL){perror("pNextNode malloc fail");return;}switch (ps->Dir){case UP://向上pNextNode->x = ps->pSnakebody->x;pNextNode->y = ps->pSnakebody->y - 1;break;case DOWN://向下pNextNode->x = ps->pSnakebody->x;pNextNode->y = ps->pSnakebody->y + 1;break;case LEFT://向左pNextNode->x = ps->pSnakebody->x - 2;pNextNode->y = ps->pSnakebody->y;break;case RIGHT://向右pNextNode->x = ps->pSnakebody->x + 2;pNextNode->y = ps->pSnakebody->y;break;}//判断下一个节点是不是食物if (NextIsFood(pNextNode, ps)){EatFood(pNextNode, ps);}else{NotFood(pNextNode, ps);}KillByWall(ps);//下一步是墙KillBySelf(ps);//下一步是自己}//运行游戏
void GameRun(pSnake ps)
{PrintHelpInfo();do{SetPos(60, 10);printf("食物分数:%2d", ps->Food_Weight);SetPos(60, 11);printf("总分数:%2d", ps->Socre);if (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->Cdt = END_NORMAL;break;}else if (KEY_PRESS(VK_SPACE)){pause();}else if (KEY_PRESS(VK_F1)){if (ps->Sleep_Time > 80){ps->Sleep_Time -= 30;ps->Food_Weight += 2;}}else if (KEY_PRESS(VK_F2)){if (ps->Sleep_Time < 320){ps->Sleep_Time += 30;ps->Food_Weight -= 2;}}//让蛇走起来SnakeMove(ps);Sleep(ps->Sleep_Time);} while (ps->Cdt == OK);}
//善后工作
void GameEnd(pSnake ps)
{SetPos(20, 12);switch (ps->Cdt){case END_NORMAL:printf("您主动结束了游戏");break;case KILL_BY_WALL:printf("您撞到墙死了");break;case KILL_BY_SELF:printf("您咬到了自己");}//释放蛇身节点pSnakeNode cur = ps->pSnakebody;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
}

snaketest.c

#define   _CRT_SECURE_NO_WARNINGS 1
#include "Snake.h"void test()
{int ch = 0;do{system("cls");Snake snake;GameStart(&snake);GameRun(&snake);GameEnd(&snake);SetPos(20, 14);printf("再来一局吗?(Y/N):");ch = getchar();while (getchar() != '\n');} while (ch == 'Y' || ch == 'y');SetPos(0, 27);
}
int main()
{//创建贪吃蛇setlocale(LC_ALL, "");srand((unsigned int)time(NULL));test();return 0;//初始化游戏//运行游戏//结束游戏
}

实现功能

在地图上我们打印墙体、蛇、食物都是使用宽字符,普通字符只占字节,宽字符占两个
中文也是两个宽字符,所以我们本地化所有类项即可

setlocale(LC_ALL, "");

再实现功能以前,我们可以将要实现的功能分成三大类:
GameStart(初始化游戏)
GameRun(运行游戏)
GameEnd(游戏善后工作)

GameStart

再绘制地图以前,我们需要设置控制台窗口的长宽:100列,30行
顺便设置窗口的名字为贪吃蛇

void GameStart(pSnake ps)
{system("mode con cols=100 lines=30");system("title 贪吃蛇");
}

隐藏光标并且获得句柄

void GameStart(pSnake ps)
{system("mode con cols=100 lines=30");system("title 贪吃蛇");//获取标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定义光标信息结构体CONSOLE_CURSOR_INFO CursorInfo;//获取光标信息GetConsoleCursorInfo(houtput, &CursorInfo);//修改CursorInfo.bVisible = false;//设置SetConsoleCursorInfo(houtput, &CursorInfo);
}

修改光标位置

void SetPos(short x, short y)
{HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x,y };SetConsoleCursorPosition(houtput, pos);
}

打印欢迎界面和功能介绍

前面提到如何定位光标位置,在每一页打印完以后暂停,并且清理该页,才会接着打印下一页

void Welcome_To_Game()
{SetPos(40, 14);printf("欢迎来到贪食蛇小游戏");SetPos(40, 25);system("pause");system("cls");SetPos(25, 14);printf("用↑ . ↓ . ← . → 分别控制蛇的移动,F1为加速,");SetPos(25, 15);printf("F2为减速,加速将得到更高的分数");SetPos(40, 24);system("pause");system("cls");
}

绘制地图

因为在后续功能中经常要用到各种图案,我们就统一在头文件里定义好

#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'
void CreateMap()
{int i = 0;//上for (i = 0; i < 29; i++){wprintf(L"%lc", WALL);}//下SetPos(0, 26);for (i = 0; i < 29; i++){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);}}

创建蛇

#define POS_X 24
#define POS_Y 5
void InitSnake(pSnake ps)
{ps->pSnakebody = NULL;pSnakeNode cur = NULL;for (int i = 0; i < 5; i++){//创建蛇身节点cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("malloc fail");return;}//设置坐标cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;//头插if (ps->pSnakebody == NULL){ps->pSnakebody = cur;}else{cur->next = ps->pSnakebody;ps->pSnakebody = cur;}}//打印身体cur = ps->pSnakebody;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//初始化贪吃蛇的数据ps->Cdt = OK;ps->Dir = RIGHT;ps->Food_Weight = 10;ps->Socre = 0;ps->Sleep_Time = 200;//单位毫秒
}

创建食物

棋盘大小:
在这里插入图片描述
要注意食物的范围

void CreateFood(pSnake ps)
{int x = 0;int y = 0;//食物的坐标在棋盘内随机生成
again:do{x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 != 0);//食物不能和蛇身冲突pSnakeNode cur = ps->pSnakebody;while (cur){if (cur->x == x && cur->y == y){goto again;}cur = cur->next;}//创建食物pSnakeNode Food = (pSnakeNode)malloc(sizeof(SnakeNode));if (Food == NULL){perror("malloc fail");return;}Food->next = NULL;Food->x = x;Food->y = y;SetPos(x, y);wprintf(L"%lc", FOOD);ps->pFood = Food;
}

GameRun

打印提示信息

在这里插入图片描述

//打印提示信息
void PrintHelpInfo()
{SetPos(60, 15);printf("不能穿墙,不能咬到自己");SetPos(60, 16);printf("用 ↑.↓.←.→ 分别控制蛇的移动,");SetPos(60, 17);printf("F1为加速,F2为减速,加速将得到更高的分数");SetPos(60, 18);printf("ESC:退出游戏,SPACE:暂停游戏");SetPos(60, 20);printf("我爱吃福鼎肉片@版权");
}

蛇每走一步

当蛇正在向某个方向走时,不能操控蛇走相反方向!

#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)
//运行游戏
void GameRun(pSnake ps)
{PrintHelpInfo();do{SetPos(60, 10);printf("食物分数:%2d", ps->Food_Weight);SetPos(60, 11);printf("总分数:%2d", ps->Socre);if (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->Cdt = END_NORMAL;break;}else if (KEY_PRESS(VK_SPACE)){pause();}else if (KEY_PRESS(VK_F1)){if (ps->Sleep_Time > 80){ps->Sleep_Time -= 30;ps->Food_Weight += 2;}}else if (KEY_PRESS(VK_F2)){if (ps->Sleep_Time < 320){ps->Sleep_Time += 30;ps->Food_Weight -= 2;}}//让蛇走起来SnakeMove(ps);Sleep(ps->Sleep_Time);} while (ps->Cdt == OK);//状态为OK才能走}

当蛇走向下一个节点时,要分为两种情况

  1. 下个节点是食物
  2. 下个节点不是食物
//蛇走的过程
void SnakeMove(pSnake ps)
{//创建下一个节点pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNextNode == NULL){perror("pNextNode malloc fail");return;}switch (ps->Dir){case UP://向上pNextNode->x = ps->pSnakebody->x;pNextNode->y = ps->pSnakebody->y - 1;break;case DOWN://向下pNextNode->x = ps->pSnakebody->x;pNextNode->y = ps->pSnakebody->y + 1;break;case LEFT://向左pNextNode->x = ps->pSnakebody->x - 2;pNextNode->y = ps->pSnakebody->y;break;case RIGHT://向右pNextNode->x = ps->pSnakebody->x + 2;pNextNode->y = ps->pSnakebody->y;break;}//判断下一个节点是不是食物if (NextIsFood(pNextNode, ps)){EatFood(pNextNode, ps);}else{NotFood(pNextNode, ps);}KillByWall(ps);//下一步是墙KillBySelf(ps);//下一步是自己}
  1. 下个节点是食物
    先判断一下
//判断下一个节点是不是食物
bool NextIsFood(pSnakeNode pn, pSnake ps)
{return (pn->x == ps->pFood->x && pn->y == ps->pFood->y);
}
//如果是食物,就吃掉,然后创建新的食物
void EatFood(pSnakeNode pn, pSnake ps)
{//头插ps->pFood->next = ps->pSnakebody;ps->pSnakebody = ps->pFood;//释放下一个位置的节点free(pn);pn = NULL;//打印pSnakeNode cur = ps->pSnakebody;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->Socre += ps->Food_Weight;CreateFood(ps);
}

为什么释放下一个位置的节点,有些同学有疑问
因为在CreateFood函数中,已经将ps->Food指向了食物节点,所以下一个位置的节点用不上的,当然要释放掉,因此,使用下一个位置的节点,释放食物节点也是可以的。
2. 下一个节点不是食物
在这里插入图片描述

//如果不是食物,就把最后一个节点释放
void NotFood(pSnakeNode pn, pSnake ps)
{//头插pn->next = ps->pSnakebody;ps->pSnakebody = pn;//最后一个节点,要释放pSnakeNode cur = ps->pSnakebody;while (cur->next->next)//打印前n个{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->pSnakebody->x == 56|| ps->pSnakebody->x == 0|| ps->pSnakebody->y == 0|| ps->pSnakebody->y == 26){ps->Cdt = KILL_BY_WALL;}
}
//判断下一步是否撞到自己
void KillBySelf(pSnake ps)
{pSnakeNode cur = ps->pSnakebody->next;while (cur){if (cur->x == ps->pSnakebody->x && cur->y == ps->pSnakebody->y){ps->Cdt = KILL_BY_SELF;}cur = cur->next;}
}

GameEnd

在这里插入图片描述

//善后工作
void GameEnd(pSnake ps)
{SetPos(20, 12);switch (ps->Cdt){case END_NORMAL:printf("您主动结束了游戏");break;case KILL_BY_WALL:printf("您撞到墙死了");break;case KILL_BY_SELF:printf("您咬到了自己");}//释放蛇身节点pSnakeNode cur = ps->pSnakebody;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
}

蛇死亡后继续游戏

到此还没有结束,如果玩家还想在玩一把呢,总不能关闭应用再重新点开吧

void test()
{int ch = 0;do{system("cls");Snake snake;GameStart(&snake);GameRun(&snake);GameEnd(&snake);SetPos(20, 14);printf("再来一局吗?(Y/N):");ch = getchar();while (getchar() != '\n');//如果输入yyyy一样可以读取} while (ch == 'Y' || ch == 'y');SetPos(0, 27);
}

在这里插入图片描述
希望这篇博客对你有所帮助!!!如果有不懂或者有错的地方欢迎私信探讨!

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

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

相关文章

apple watch上watchOS网络低级别和高级别区别,以及使用tcp/udp或者websocket的限制条件

可以直接看官方文档&#xff1a;TN3135: Low-level networking on watchOS | Apple Developer Documentation 高级网络&#xff1a;包括 URLSession 中的 HTTP 和 HTTPS 支持&#xff0c;以及在此之上的任何代码层。 低层网络&#xff1a;包括网络框架、 NSStream 和任何其他…

第 402 场 LeetCode 周赛题解

A 构成整天的下标对数目 I 计数&#xff1a;遍历 h o u r s hours hours &#xff0c;记录 h o u r s [ i ] % 24 hours[i]\%24 hours[i]%24 的出现次数 class Solution {public:long long countCompleteDayPairs(vector<int>& hours) {vector<int> cnt(24);…

苹果的后来者居上策略:靠隐私保护打脸微软

01.苹果与微软相比更注重用户隐私 我一直是Windows的忠实用户&#xff0c;但微软疯狂地将人工智能融入一切&#xff0c;让我开始觉得应该咬咬牙换成Mac。 自小我几乎只用Windows电脑&#xff0c;所以我对MacOS一直不太适应。虽然Windows 11有其缺点&#xff0c;但总的来说&am…

Pytorch构建vgg16模型

VGG-16 1. 导入工具包 import torch.optim as optim import torch import torch.nn as nn import torch.utils.data import torchvision.transforms as transforms import torchvision.datasets as datasets from torch.utils.data import DataLoader import torch.optim.lr_…

阿里CEO个人投资的智驾公司,走了不一样的路

佑驾创新在去年8月和11月完成两轮融资&#xff0c;在今年5月底递表港交所&#xff0c;目前拿到了29家车企88款车型的量产订单。自动驾驶赛道不缺明星&#xff0c;这些因素本不足以凸显它的差异化。但是在招股书中&#xff0c;一条特殊的发展路线&#xff0c;却让佑驾创新显得不…

DB9母头接口定义485

在通信技术中&#xff0c;DB9接口广泛应用于串行通信&#xff0c;尤其是在RS232和RS485标准中。虽然DB9接口最常见于RS232通信&#xff0c;但通过适当的引脚映射&#xff0c;它也可以用于RS485通信。本文将详细介绍如何定义和使用DB9母头接口进行RS485连接。 DB9母头接口简介 …

②-Ⅱ单细胞学习-组间及样本细胞比例分析(补充)

数据加载 ①单细胞学习-数据读取、降维和分群_subset函数单细胞群-CSDN博客‘ #2024年6月20日 单细胞组间差异分析升级# rm(list = ls()) library(Seurat)#数据加载(在第一步已经处理好的数据) load("scedata1.RData")#这里是经过质控和降维后的单细胞数据 tabl…

蓝牙模块在智能城市构建中的创新应用

随着科技的飞速发展&#xff0c;智能城市的概念已经逐渐从理论走向实践。物联网技术作为智能城市构建的核心驱动力&#xff0c;正在推动着城市基础设施、交通管理、环境监测等领域的深刻变革。蓝牙模块&#xff0c;作为物联网技术的重要组成部分&#xff0c;以其低功耗、低成本…

java文件IO操作

前言&#xff1a; java里面的文件操作分为文件系统操作和文件内容操作。文件系统操作主要是针对File这个类来进行操作&#xff0c;而文件内容操作总的来说有四个&#xff1a;Reader&#xff0c;Writer&#xff0c;InputStream&#xff0c;OutputStream&#xff0c;前面两个是通…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(七)质量相关法律法规及《管理体系审核员准则》2021修订3

5、质量管理体系基础考试大纲 3.3法律法规和其他要求 a)《中华人民共和国民法典》第三编 合同&#xff1b; b)《中华人民共和国消费者权益保护法》 c)《中华人民共和国产品质量法》 d) 中国认证认可协会相关人员注册与管理要求 目 录 前 言 第一章 总则 1.1 引言 1.2 适…

重学java 79.JDK新特性 ⑤ JDK8之后的新特性

别怕失败&#xff0c;大不了重头再来 —— 24.6.20 一、接口的私有方法 Java8版本接口增加了两类成员: 公共的默认方法 公共的静态方法 Java9版本接口又新增了一类成员: 私有的方法 为什么IDK1.9要允许接口定义私有方法呢? 因为我们说接口是规范&#xff0c;规范是…

由于找不到msvcp140.dll无法继续执行代码是什么意思,解决msvcp140.dll文件

由于找不到msvcp140.dll无法继续执行代码这种提示&#xff0c;你知道要怎么去处理么&#xff1f;出现这情况&#xff0c;你的程序就代表出现问题了&#xff0c;你会发现打不开&#xff0c;我们需要修复msvcp140.dll文件才能正常的使用程序。今天我们就来聊聊msvcp140.dll找不到…

加密好的WPSword文档,忘记密码怎么办?

在日常办公和学习中&#xff0c;我们经常使用WPS Word等文档处理软件来创建和编辑重要文件。为了保护这些文件不被未经授权的人访问&#xff0c;我们通常会选择给文档设置密码。然而&#xff0c;有时我们可能会因为时间久远或其他原因而忘记自己设置的密码&#xff0c;这时该如…

【Go】用 DBeaver、db browser 和 SqlCipher 读取 SqlCipher 数据库

本文档主要描述如何用 DBeaver、db browser 和 SqlCipher 上打开加密的 SQLite3 数据库(用 SqlCipher v3 加密) 软件版本 DBeaver&#xff1a;v24.1.0 SQLite-driver: sqlite-jdbc-3.46.0.0.jar dbbrowser-for-sqlite-cipher&#xff1a;3.12.2 SqlCipher cli(ubuntun)&am…

如何避免在React中的回调函数中使用箭头函数可能引起的内存泄漏?

在React中&#xff0c;箭头函数在回调函数中的使用确实可能引发性能问题&#xff0c;尤其是当这些函数在渲染方法或者组件内部被定义时。每次组件重新渲染时&#xff0c;都会创建这些函数的新实例&#xff0c;这可能导致不必要的计算和内存使用&#xff0c;甚至在某些情况下引发…

2024年了,上大学可以不需要用到电脑吗?

前言 在2024年的今天&#xff0c;电脑已经成为了人们工作生活的一大部分。Oh, no&#xff01;好像手机才是。 好像每个人都是这样的&#xff1a;可以没有电脑&#xff0c;但不能没有手机…… 所以2024年的今天&#xff0c;上大学的小伙伴们可以不需要用到电脑吗&#xff1f;…

3D打印随形透气钢引领模具排气新潮流

随着模具制造技术的不断发展&#xff0c;金属3D打印技术正逐渐成为模具制造领域的一大亮点。除了已广泛应用的随形水路技术外&#xff0c;金属3D打印在解决模具困气问题上同样展现出独特优势&#xff0c;成为模具排气、解决困气的重要技术方向。 模具的排气系统一直是模具设计制…

前端菜鸡学习日记 -- computed和watch的用法

目录 1.computed&#xff1a; 2.watch&#xff1a; 哈喽哇大家&#xff0c;又是新的一周&#xff0c;因为一些特殊的原因&#xff0c;所以目前是比较闲的&#xff0c;就趁机多学习一点东西把&#xff0c;这些学习日记就是学习中的笔记咯&#xff0c;流水账日记则是工作中遇到…

USB CDC简介

USB CDC类、USB2.0标准与PSTN之间的关系 CDC(Communication Device Class)类是USB2.0标准下的一个子类&#xff0c;定义了通信相关设备的抽象集合。它与USB2.0标准以及其下的子类的相互关系如下图所示: 如上图&#xff0c;USB2.0标准下定义了很多子类&#xff0c;有音频类&…

计算机网络知识点汇总(三)

1.2 计算机网络体系结构与参考模型 1.2.1 计算机网络分层结构 计算机网络的各层及其协议的集合称为网络的体系结构(Architecture)。换言之&#xff0c;计算机网络的体系结构就是这个计算机网络及其所应完成的功能的精确定义。要强调的是&#xff0c;这些功能究竟是用何种硬件…