基于C语言的贪吃蛇小游戏(简易版)

这篇博客会是对学习C语言成果的检测,为了实现贪吃蛇小游戏,我们用到的“工具”有:C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。

目录

1.简易版游戏效果

1.1欢迎界面

1.2游戏规则提示页面

1.3游戏进行页面

1.4游戏结束页面

2.游戏需要实现的内容

3.Win32 API介绍 

3.1Win32 API 

3.2控制台程序 

3.3控制台屏幕上的坐标COORD 

3.4游戏实现是可能用到的Win32 API 函数

3.4.1GetStdHandle

3.4.1.1函数格式

 3.4.1.2使用样例

3.4.2GetConsoleCursorInfo

3.4.2.1函数格式

3.4.2.1.1 CONSOLE_CURSOR_INFO 

3.4.2.2使用样例 

3.4.3SetConsoleCursorInfo

3.4.3.1函数格式

3.4.3.2使用样例

3.4.4SetConsoleCursorPosition

3.4.4.1函数格式

3.4.4.2使用样例 

3.4.5GetAsyncKeyState

3.4.5.1函数格式

3.4.5.2使用样例

 3.5其余相关知识点

3.5.1本地化

3.5.1.1类项

3.5.1.2setlocale函数 

3.5.1.2.1函数格式

3.5.1.2.2使用样例 

3.5.2宽字符的打印

4.游戏流程设置

5.游戏实现代码 

5.1 Snake.h

5.2 Snake.c

5.3 tool.h

5.4 tool.c

5.5 main.c


1.简易版游戏效果

关于本人实现的贪吃蛇 ,有四个展示页面:

1.1欢迎界面

1.2游戏规则提示页面

 

1.3游戏进行页面

 

1.4游戏结束页面

 

2.游戏需要实现的内容

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

实现环境:Windows环境的控制台

3.Win32 API介绍 

3.1Win32 API 

简单来说就是包含在一个附加名为DLL的动态连接库文件中的一类函数

 Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程序达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application),所以便称之为 Application Programming Interface,简称 API 函数。WIN32 API也就是Microsoft Windows 32位平台的应用程序编程接口。

3.2控制台程序 

平常我们运行起来的黑框程序其实就是控制台程序

我们可以使用cmd命令中的mode命令来设置控制台窗口的长宽:

设置控制台窗口的大小,30行,100列

mode con cols=100 lines=30

使用title命令设置控制台窗口名字: 贪吃蛇

title 贪吃蛇

如果在修改过程中发现无法修改窗口大小,此时需要将控制台程序的默认终端应用程序改为“让Windows决定”,如果还是无法修改(有些电脑无法做到,比如我的),则再将其改为Windows控制台主机

3.3控制台屏幕上的坐标COORD 

COORD 是Windows API中定义的一个结构体,表示一个字符在控制台屏幕幕缓冲区上的坐标,坐标系 (0,0) 的原点位于缓冲区的顶部左侧单元格。 横着向右是x轴,竖着向下是y轴。

以下是COORD类型结构体的声明: 

typedef struct _COORD {SHORT X;SHORT Y;
} COORD, *PCOORD;

3.4游戏实现是可能用到的Win32 API 函数

3.4.1GetStdHandle

GetStdHandle是一个Windows API函数。它用于从一个特定的标准设备(标准输入、标准输出或标准错误)中取得一个句柄(用来标识不同设备的数值),使用这个句柄可以操作设备。 

可以理解为我们通过这个函数获取对标准输入、标准输出或标准错误的控制权,这个权杖就是存放函数返回值的指针

3.4.1.1函数格式
HANDLE GetStdHandle(DWORD nStdHandle);

 

 3.4.1.2使用样例

 例如想要获取对标准输出的控制权。

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值) 
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

3.4.2GetConsoleCursorInfo

检索有关指定控制台屏幕缓冲区的光标大小可见性的信息 

3.4.2.1函数格式
BOOL WINAPI GetConsoleCursorInfo(HANDLE hConsoleOutput,PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);

  

3.4.2.1.1 CONSOLE_CURSOR_INFO 

包含有关控制台光标的信息的结构体 

typedef struct _CONSOLE_CURSOR_INFO {DWORD dwSize;BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
3.4.2.2使用样例 
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值) 
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息 

3.4.3SetConsoleCursorInfo

 设置指定控制台屏幕缓冲区的光标的大小可见性

3.4.3.1函数格式
BOOL WINAPI SetConsoleCursorInfo(HANDLE hConsoleOutput,const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

 

3.4.3.2使用样例
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作 
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息 
CursorInfo.bVisible = false; //隐藏控制台光标 
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态 

3.4.4SetConsoleCursorPosition

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调用SetConsoleCursorPosition函数将光标位置设置到指定的位置。  

3.4.4.1函数格式
BOOL WINAPI SetConsoleCursorPosition(HANDLE hConsoleOutput,COORD pos
);

 

3.4.4.2使用样例 
COORD pos = { 10, 5};
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值) 
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//设置标准输出上光标的位置为pos 
SetConsoleCursorPosition(hOutput, pos);

3.4.5GetAsyncKeyState

获取按键情况

GetAsyncKeyState的返回值是short类型,在上一次调用 GetAsyncKeyState 函数后,如果返回的16位的short数据中:

  • 如果最高位是1,说明按键的状态是按下
  • 如果最高是0,说明按键的状态是抬起
  • 如果最低位被置为1,则说明该按键被按过,反之为0
3.4.5.1函数格式
SHORT GetAsyncKeyState(int vKey);

vKey是虚拟密钥代码(下面为链接)

https://learn.microsoft.com/zh-cn/windows/win32/inputdev/virtual-key-codes 

展示本游戏要用到的虚拟密钥代码 :

VK_SPACE0x20空格键
VK_F30x72F3 键
VK_F40x73F4 键
VK_ESCAPE0x1BESC 键
VK_LEFT0x25LEFT ARROW 键
VK_UP0x26UP ARROW 键
VK_RIGHT0x27RIGHT ARROW 键
VK_DOWN0x28DOWN ARROW 键
3.4.5.2使用样例
#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )
#include <stdio.h>
#include <windows.h>
int main()
{while (1){if (KEY_PRESS(0x30)){printf("0\n");}else if (KEY_PRESS(0x31)){printf("1\n");}else if (KEY_PRESS(0x32)){printf("2\n");}else if (KEY_PRESS(0x33)){printf("3\n");}else if (KEY_PRESS(0x34)){printf("4\n");}else if (KEY_PRESS(0x35)){printf("5\n");}}return 0;
}

 3.5其余相关知识点

3.5.1<locale.h>本地化

 <locale.h>提供的函数用于控制C标准库中对于不同的地区会产生不一样行为的部分。

在标准中,依赖地区的部分有以下几项:

• 数字量的格式

• 货币量的格式

• 字符集

• 日期和时间的表示形式

3.5.1.1类项

通过修改地区,程序可以改变它的行为来适应世界的不同区域。

但地区的改变可能会影响库的许多部分,其中一部分可能是我们不希望修改的。所以C语言支持针对不同的类项进行修改,下面的一个宏, 指定一个类项:

  • LC_COLLATE:影响字符串比较函数 strcoll() 和 strxfrm() 。
  • LC_CTYPE:影响字符处理函数的行为。
  • LC_MONETARY:影响货币格式。
  • LC_NUMERIC:影响 printf() 的数字格式。
  • LC_TIME:影响时间格式 strftime() 和 wcsftime() 。
  • LC_ALL:针对所有类项修改,将以上所有类别设置为给定的语言环境。
3.5.1.2setlocale函数 
3.5.1.2.1函数格式
char* setlocale (int category, const char* locale);

setlocale函数用于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。 setlocale的第一个参数可以是前面说明的类项中的一个,那么每次只会影响一个类项,如果第一个参数是LC_ALL,就会影响所有的类项。 C标准给第二个参数仅定义了2种可能取值:"C"(正常模式)"  "(本地模式)。 

3.5.1.2.2使用样例 

切换到我们的本地模式后就支持宽字符(汉字)的输出

setlocale(LC_ALL, " ");//切换到本地环境 

3.5.2宽字符的打印

过去C语言并不适合非英语国家(地区)使用。 C语言最初假定字符都是单字节的。但是这些假定并不是在世界的任何地方都适用。为了使C语言适应国际化,C语言的标准中不断加入了国际化的支持。比如:加入了宽字符的类型 wchar_t 和宽字符的输入和输出函数,加入了头文件,其中提供了允许程序员针对特定地区(通常是国家或者说某种特定语言的地理区域)调整程序行为的函数。 

宽字符的字面量必须加上前缀“L”,否则 C 语言会把字面量当作窄字符类型处理。前缀“L”在单引 号前面,表示宽字符,对应 wprintf() 的占位符为 %lc ;在双引号前面,表示宽字符串,对应 wprintf() 的占位符为 %ls  

以下为举例:

#include <stdio.h>
#include<locale.h>
int main() {setlocale(LC_ALL, "");wchar_t ch1 = L'●';wchar_t ch2 = L'★';wprintf(L"%lc\n", ch1);wprintf(L"%lc\n", ch2);return 0;
}

4.游戏流程设置

 

程序开始就设置程序支持本地模式,

然后进入游戏的主逻辑。 主逻辑分为3个过程:

  1. 游戏开始:完成游戏的初始化
  2. 游戏运行:完成游戏运行逻辑的实现
  3. 游戏结束:完成游戏结束的说明,实现资源释放 

5.游戏实现代码 

5.1 Snake.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include"tool.h"
#include"locale.h"
#include<Windows.h>
#include<stdbool.h>
#include"vld.h"
#define ROW 60
#define CON 30
#define SROW 20//蛇的初始列
#define SCON 5//蛇的初始行
#define WALL L'囧'
#define SNAKE L'●'
#define FOOD L'★'
#define KEY_PRESS(vk) (GetAsyncKeyState(vk) & 1)enum State
{OK = 1,//正常运行PAUSE,//暂停ESC,//正常退出KILL_BY_SELF,//撞到自己KILL_BY_WALL//撞墙
};
enum Dir {UP=1,//上DOWN,//下LEFT,//左RIGHT//右
};
typedef struct SnakeNode {int x;int y;//坐标struct SnakeNode* next;
}SnakeNode,*pSnakeNode;typedef struct Snake {pSnakeNode phead;enum State _state;//蛇状态int _score;//得分int food_score;//食物分数SnakeNode _food;//食物节点enum Dir dir;//方向int _sleep;//睡眠时间}Snake;//函数声明
void InitGame(Snake* psnake);//初始化游戏
void Welcome();//欢迎界面
void MapInit();//打印地图
void SnakeInit(Snake*snake);//初始化贪吃蛇
void Game(Snake* snake);//游戏运行
void PutFood(Snake* snake);//放置食物void Pause();//暂停
//释放链表节点
void Relese(pSnakeNode phead);

5.2 Snake.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Snake.h"
#include"tool.h"
//初始化游戏
void InitGame(Snake*psnake)
{//初始化界面system("mode con cols=80 lines=40");system("title 贪吃蛇");//隐藏光标HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO cursorinfo;GetConsoleCursorInfo(houtput, &cursorinfo);//获取控制台光标信息 cursorinfo.bVisible = false;SetConsoleCursorInfo(houtput, &cursorinfo);//初始化贪吃蛇信息psnake->dir = RIGHT;psnake->food_score = 10;psnake->phead = NULL;psnake->_score = 0;psnake->_state = OK;psnake->_sleep = 200;}
//欢迎界面
void Welcome()
{//打印欢迎信息setpos(30, 19);printf("欢迎来到贪吃蛇小游戏!\n");setpos(32, 20);system("pause");system("cls");//打印规则setpos(16, 19);printf("用↑ . ↓ . ← . →控制蛇的移动,F3加速,F4减速");setpos(16, 20);printf("不同速度得分不同");setpos(28, 21);system("pause");system("cls");}
//打印地图
void MapInit()
{int i;//上setpos(0, 0);for (i = 0; i < ROW; i += 2){wprintf(L"%lc", WALL);}//下setpos(0, 29);for (i = 0; i < ROW; i += 2){wprintf(L"%lc", WALL);}//左for(i=1;i<CON-1;i++){setpos(0, i);wprintf(L"%lc", WALL);}//右for (i = 1; i < CON - 1; i++){setpos(58, i);wprintf(L"%lc", WALL);}}//初始化贪吃蛇
void SnakeInit(Snake*snake)
{int i = 0;pSnakeNode cur = snake->phead;for (i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("malloc cur");return;}cur->x = SROW+i*2;cur->y = SCON;//头插cur->next = snake->phead;snake->phead = cur;}PrintNode(snake);}
//放置食物
void PutFood(Snake* snake)
{pSnakeNode food = (pSnakeNode)malloc(sizeof(SnakeNode));if (food == NULL){perror("malloc food");return;}
again:do{food->x = rand() % 56 + 1;food->y = rand() % 28 + 1;food->next = NULL;} while (food->x % 2 != 0);//pSnakeNode cur = snake->phead;//食物不能在蛇身上while (cur){if (cur->x == food->x && cur->y == food->y)goto again;cur = cur->next;}//赋值snake->_food = *food;//打印setpos(snake->_food.x, snake->_food.y);wprintf(L"%lc", FOOD);free(food);}
//暂停
void Pause()
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE) == 1)break;}
}//游戏运行
void Game(Snake* snake){//显示规则setpos(62, 8);printf("规则:");setpos(62, 9);printf("1.不要撞墙");setpos(62, 10);printf("2.不要撞到自己");setpos(62, 11);printf("3.F3加速");setpos(62, 12);printf("4.F4减速");setpos(62, 13);printf("5.空格暂停");setpos(62, 14);printf("6.Esc退出");//放置食物PutFood(snake);//蛇移动(更新数据)while (snake->_state == OK){setpos(62, 5);printf("当前食物分值:%2d", snake->food_score);setpos(62, 6);printf("当前得分:%d", snake->_score);pSnakeNode pnext = (pSnakeNode)malloc(sizeof(SnakeNode));if (pnext == NULL){perror("malloc pnext fail");return;}//按键判断//方向判断if (KEY_PRESS(VK_UP) == 1 && snake->dir != DOWN){snake->dir = UP;}else if (KEY_PRESS(VK_DOWN) == 1 && snake->dir != UP){snake->dir = DOWN;}else if (KEY_PRESS(VK_LEFT) == 1 && snake->dir != RIGHT){snake->dir = LEFT;}else if (KEY_PRESS(VK_RIGHT) == 1 && snake->dir != LEFT){snake->dir = RIGHT;}else if (KEY_PRESS(VK_SPACE) == 1)//判断暂停{Pause();}else if (KEY_PRESS(VK_ESCAPE) == 1)//判断退出{snake->_state = ESC;setpos(26, 14);printf("已退出");break;}else if (KEY_PRESS(VK_F3) == 1)//加速{if(snake->_sleep>80){snake->_sleep -= 50;snake->food_score += 2;}}else if (KEY_PRESS(VK_F4) == 1)//减速{if (snake->food_score > 2){snake->_sleep += 50;snake->food_score -= 2;}}//刷新蛇身信息if (snake->dir == UP){pnext->x = snake->phead->x;pnext->y = snake->phead->y - 1;}else if (snake->dir == DOWN){pnext->x = snake->phead->x;pnext->y = snake->phead->y + 1;}else if (snake->dir == LEFT){pnext->x = snake->phead->x - 2;pnext->y = snake->phead->y;}else if (snake->dir == RIGHT){pnext->x = snake->phead->x + 2;pnext->y = snake->phead->y;}//状态判断//吃到食物if (pnext->x == snake->_food.x && pnext->y == snake->_food.y){pnext->next = snake->phead;snake->phead = pnext;PrintNode(snake);PutFood(snake);snake->_score += snake->food_score;}else {//没有食物pnext->next = snake->phead;snake->phead = pnext;pSnakeNode cur = snake->phead;while (cur->next->next){cur = cur->next;}setpos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;PrintNode(snake);}//撞墙if (pnext->x == 0 || pnext->x == 58 || pnext->y == 0 || pnext->y == 29){snake->_state = KILL_BY_WALL;setpos(26, 14);printf("您撞墙了");}//撞自己pSnakeNode cur = snake->phead->next;while (cur){if (snake->phead->x == cur->x && snake->phead->y == cur->y){snake->_state = KILL_BY_SELF;setpos(26, 14);printf("您撞上了自己");break;}cur = cur->next;}Sleep(snake->_sleep);}}
//释放链表节点
void Relese(pSnakeNode phead)
{pSnakeNode cur=phead;while (phead){cur = phead;phead = phead->next;free(cur);}//出函数后要置空phead
}

5.3 tool.h

#pragma once
#include<Windows.h>
#include<stdbool.h>
//前置声明
typedef struct SnakeNode* pSnakeNode;
typedef struct Snake Snake;
//函数声明//定位光标
void setpos(int x,int y);
//打印节点
void PrintNode(Snake* snake);

5.4 tool.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"tool.h"
#include"Snake.h"
//定位光标
void setpos(int x,int y){HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(houtput, pos);
}
//打印节点
void PrintNode(Snake* snake)
{pSnakeNode cur = snake->phead;while(cur){setpos(cur->x, cur->y);wprintf(L"%lc", SNAKE);cur = cur->next;}}

5.5 main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Snake.h"
void test(Snake* snake) {//显示欢迎,提示页面Welcome();//初始化地图MapInit();//初始化贪吃蛇SnakeInit(snake);//游戏运行Game(snake);//结束善后//释放链表节点Relese(snake->phead);snake->phead = NULL;setpos(22, 15);
}
int main()
{int a;//初始化本地环境setlocale(LC_ALL, "");do{a = 0;system("cls");//初始化游戏srand((unsigned int)time(NULL));Snake snake = { 0 };InitGame(&snake);//游戏逻辑test(&snake);printf("是否再来一局(1.Yes/0.No):");scanf("%d", &a);} while (a == 1);setpos(0, 30);return 0;
}

 --------------------------------------------------------------------------------------------------------------------------------

好啦,关于贪吃蛇小游戏的实现讲解就先到这里啦,看完的小伙伴记得关注支持一下博主哦~

有问题欢迎在下方提问~

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

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

相关文章

纯净水20、脉动30被指宰客!疯狂开始反噬小杨哥?

作为疯狂小杨哥早期粉&#xff0c;小柴好像很久没看到小杨哥的搞笑视频了。 自然&#xff0c;再在社交媒体上看到&#xff0c;小杨哥兄弟已经不再是那个青涩的少年了。 而是摇身一变不仅成为一个非常成功带货主播&#xff0c;且成为一个资本版图越来越多&#xff0c;玩的越来越…

现场面试题

这里写目录标题 1.sql1.1 只保留学生的最新成绩1.2 统计通话号码数1.3 更新地址 2.基础题2.1 请求序列第N位的值: 0, 1, 1, 2, ,3, 5, 8, 13, 21, 34.....第N位的值2.2 请写一段java代码&#xff0c;输出存在重复字母的单词 1.sql 1.1 只保留学生的最新成绩 表student中记录学…

网络安全之交换基础

交换属于二层技术。路由器&#xff08;router&#xff09;是三层设备&#xff0c;可以基于IP地址转发&#xff0c;但需要路由表来记录。 交换机&#xff08;switch&#xff09;是二层设备&#xff0c;网桥&#xff08;switch&#xff09;也是二层设备&#xff0c;这两个都是基…

SegFix:预测边界和预测方向来修正边界

论文标题&#xff1a;SegFix: Model-Agnostic Boundary Refinement for Segmentation 论文地址&#xff1a;https://arxiv.org/pdf/2007.04269.pdf 代码地址&#xff1a;https://github.com/openseg-group/openseg.pytorch 两种loss监督 八种方向变回归问题为分类问题 代码地…

PyQt6--Python桌面开发(1.安装配置环境)

一.PyQt6简介 PyQt&#xff1a;PyQt是一个功能强大且成熟的GUI框架&#xff0c;基于Qt库。它提供了丰富的组件、布局和主题选项&#xff0c;以及强大的功能和灵活性。PyQt的优点是它具有现代化的外观和丰富的功能&#xff0c;适用于复杂的GUI应用程序。然而&#xff0c;由于Py…

openEuler 22.03 GPT分区表模式下磁盘分区管理

目录 GPT分区表模式下磁盘分区管理parted交互式创建分区步骤 1 执行如下步骤对/dev/sdc磁盘分区 非交互式创建分区步骤 1 输入如下命令直接创建分区。 删除分区步骤 1 执行如下命令删除/dev/sdc1分区。 GPT分区表模式下磁盘分区管理 parted交互式创建分区 步骤 1 执行如下步骤…

明火检测实时识别报警:视觉算法助力安全生产管理

背景与现状 在各种工作、生产环境下&#xff0c;明火的存在往往是潜在的安全隐患。无论是加油站、化工园区、仓储场所还是校园&#xff0c;明火一旦失控就会引发火灾&#xff0c;造成严重的人员伤亡和财产损失。传统的明火检查手段主要依赖于人工巡查和定期的消防检查&#xf…

什么是高级持续威胁(APT)

高级持续性威胁&#xff08;Advanced Persistent Threat&#xff0c;APT&#xff09;&#xff0c;又叫高级长期威胁&#xff0c;是一种复杂的、持续的网络攻击&#xff0c;包含三个要素&#xff1a;高级、长期、威胁。 【高级】是指执行APT攻击需要比传统攻击更高的定制程度和…

小米手机短信删除了怎么恢复?这里教你快速解决!

手机已经成为我们生活中不可或缺的一部分&#xff0c;比如小米手机。我们通过手机进行通讯、娱乐、学习等各种活动&#xff0c;其中&#xff0c;短信是我们日常生活中的重要信息来源之一。然而&#xff0c;我们可能会不小心删除了一些重要的短信&#xff0c;这时候我们就会想知…

领航法律科技,法大大多年深耕再获认可!

近日&#xff0c;“乘势破局 第八届新兴法律服务业高峰论坛”在上海隆重举行。作为国内领先的电子签厂商&#xff0c;法大大凭借在法律科技领域的多年深耕与沉淀&#xff0c;荣获“法律科技领航机构”称号。 据悉&#xff0c;新兴法律服务业高峰论坛作为国内首个聚焦“新兴法律…

高等数学笔记(下中)

曲线积分 第一类曲线积分&#xff1a;对弧长的积分计算方法 定理&#xff1a;设 f ( x , y ) f(x,y) f(x,y)在曲线弧 L L L上有定义且连续&#xff0c; L L L的参数方程是 { x φ ( t ) y ψ ( t ) ( α ≤ t ≤ β ) \begin{cases} x\varphi(t)\\ y\psi(t) \end{cases}(\a…

一文了解什么是SSL证书?——值得收藏

SSL证书&#xff0c;全称Secure Sockets Layer证书&#xff0c;是一种网络安全协议的实现方式&#xff0c;现在通常指的是其继任者TLS&#xff08;Transport Layer Security&#xff09;证书&#xff0c;不过习惯上仍称为SSL证书。它的主要作用是确保互联网上的数据传输安全&am…

WebStorm2024版 将项目上传到gitee

目录 一、准备 WebStorm gitee 二、上传代码到Gitee 三、过程中遇到的问题 报错&#xff1a;You may want to first integrate the remote changes (e.g., git pull ...) before pushing again. 报错&#xff1a;fatal: refusing to merge unrelated histories 报错&a…

机器人系统ros2-开发实践05-ROS2 中 tf2的定义及示例说明

1. what ros2 tf2 &#xff1f; tf2的全称是transform2&#xff0c;在ROS&#xff08;Robot Operating System&#xff09;中&#xff0c;它是专门用于处理和变换不同坐标系间位置和方向的库。这个名字来源于“transform”这个词&#xff0c;表示坐标变换&#xff0c;而“2”则…

如何判断代理IP质量?

由于各种原因&#xff08;从匿名性和安全性到绕过地理限制&#xff09;&#xff0c;代理 IP 的使用变得越来越普遍。然而&#xff0c;并非所有代理 IP 都是一样的&#xff0c;区分高质量和低质量的代理 IP 对于确保流畅、安全的浏览体验至关重要。以下是评估代理 IP 质量时需要…

C语言 main( ) 函数的指针数组形参是怎么回事?

一、问题 在使⽤⼀些开发⼯具⽣成C语⾔⽂件时&#xff0c;主函数 mian( ) 中会有参数&#xff0c;这个参数到底是怎么回事⼉呢&#xff1f; 二、解答 mian( ) 称为主函数&#xff0c;是所有程序运⾏的⼊口。 mian( ) 函数是由系统调⽤的&#xff0c;当处于操作命令状态下&…

【算法】滑动窗口——最大连续1的个数

本篇文章讲的是“最大连续1的个数”这道题&#xff0c;从最开始的简单暴力到用滑动窗口算法实现解题的思路历程&#xff0c;有需要借鉴即可。 目录 1.题目2.暴力求解3.滑动窗口解法3.1优化一&#xff1a;end重返start优化&#xff0c;end指针不回退3.2优化二&#xff1a;某一st…

【Android项目】“追茶到底”项目介绍

没有多的介绍&#xff0c;这里只是展示我的项目效果&#xff0c;后面会给出具体的代码实现。 一、用户模块 1、注册&#xff08;第一次登陆的话需要先注册账号&#xff09; 2、登陆&#xff08;具有记住最近登录用户功能&#xff09; 二、点单模块 1、展示饮品列表 2、双向联动…

Go语言系统学习笔记(一):基础篇

1. 写在前面 公司的新业务开发需要用到go语言&#xff0c;虽然之前没接触过这门语言&#xff0c;但在大模型的帮助下&#xff0c;边看项目边写代码也能进行go的项目开发&#xff0c;不过&#xff0c;写了一段时间代码之后&#xff0c;总感觉对go语言本身&#xff0c;我的知识体…