基于链表实现贪吃蛇游戏
本文中,我们将使用链表和一些Win32 API的知识来实现贪吃蛇小游戏
一、功能
(1)游戏载入界面
(2)地图的绘制
(3)蛇身的移动和变长
(4)食物的生成
(5)死亡判定
(6)计算得分
(7)退出游戏和暂停游戏
实现贪吃蛇小游戏,我们需要创建3个文件来实现不同的部分
- Snake.c:游戏函数的实现
- Snake.h:结构体定义、头文件引用、宏定义和函数声明
- test.c:主函数的实现
二、Snake.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <stdbool.h>
#include <locale.h>#define KEY_PRESS(VK) ((GetAsyncKeyState(VK) & 0x1) ? 1 : 0)#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'//蛇的初始位置
#define POS_X 24
#define POS_Y 5enum GAME_STATUS
{RUN,ESC,KILL_BY_WALL,KILL_BY_SELF,
};enum DIRECTION
{UP,DOWN,LEFT,RIGHT,
};//蛇⾝节点
typedef struct SnakeNode
{short x;short y;struct SnakeNode* next;
}SnakeNode;typedef struct Snake
{SnakeNode* pSnake;//指向蛇头SnakeNode* Food; int SleepTime;int Score;int FoodScore;enum GAME_STATUS Status;enum DIRECTION Dir;
}Snake;void GameStart(Snake* ps);void GameRun(Snake* ps);void GameEnd(Snake* ps);void SetPos(short x, short y);//设置光标坐标void WelcomeToGame();//欢迎界面void CreateMap();//创建地图void InitSnake(Snake* ps);//初始化蛇void CreateFood(Snake* ps);//生成食物void PrintHelpInfo();//打印教程void SnakeMove(Snake* ps);//蛇身移动void EatFood(Snake* ps, SnakeNode* next);//移动后吃到食物void NotEatFood(Snake* ps, SnakeNode* next);//移动后没吃到食物void KillByWall(Snake* ps);//检测是否撞墙void KillBySelf(Snake* ps);//检测是否撞到自己
三、Snake.c
在Snake.c中,我们将整个游戏拆分成游戏前的准备、游戏运行中和游戏结束后三部分
首先要在头文件中定义蛇的节点等相关信息
enum GAME_STATUS //游戏状态的枚举
{RUN, //游戏正常运行中ESC, //正常退出游戏KILL_BY_WALL, //撞到墙导致游戏结束KILL_BY_SELF, //撞到自己导致游戏结束
};enum DIRECTION //蛇身方向的枚举
{UP,DOWN,LEFT,RIGHT,
};//蛇⾝节点
typedef struct SnakeNode
{short x; //x轴坐标short y; //y轴坐标struct SnakeNode* next;
}SnakeNode;typedef struct Snake
{SnakeNode* pSnake; //指向蛇头SnakeNode* Food; //指向食物int SleepTime; //蛇身运动的速度int Score; //总分数int FoodScore; //每个食物的分数enum GAME_STATUS Status; //游戏运行的状态enum DIRECTION Dir; //蛇身方向
}Snake;
接下来就可以开始设计游戏前的准备程序了
2.1 游戏前的准备
为了美观,我们可以使用一些cmd命令来设置控制台窗口的长宽等信息
控制台窗口实际上是有坐标的,也就是有行和列的
最左上角的位置的坐标为(0,0),像这样的一个字符高为1 宽为1
所以我们可以通过cmd命令将控制台设置为30行,100列,并将标题改成贪吃蛇
void GameStart(Snake* ps)
{system("mode con cols=100 lines=30");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);
}
将剩下的四个功能分别分装在四个函数中
(1)欢迎界面
void WelcomeToGame()//欢迎界面
{SetPos(45, 10);printf("欢迎来到贪吃蛇小游戏");SetPos(45, 15);system("pause");system("cls");SetPos(35, 10);printf("用 ↑.↓.←.→ 控制蛇的行动,F3为加速,F4为减速");SetPos(35, 11);printf("加速能得到更多的分数");SetPos(45, 15);system("pause");system("cls");
}
其中,SetPos函数是用来设置光标坐标的,因为在控制台中printf中的内容会从光标的位置开始打印。
void SetPos(short x, short y) // 设置光标坐标
{COORD pos = {x, y};HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorPosition(handle, pos);
}
完成后的效果如下:
(2)创建地图
创建地图时需要用到宽字符的打印,宽字符也就是高为1 宽为2的字符,需要用wprintf函数打印
void CreateMap() // 创建地图
{SetPos(0, 0);int i = 0;for (i = 0; i < 58; i += 2){SetPos(i, 0);wprintf(L"%lc", L'□');}for (i = 0; i < 58; i += 2){SetPos(i, 26);wprintf(L"%lc", L'□');}for (i = 1; i < 26; i++){SetPos(0, i);wprintf(L"%lc", L'□');}for (i = 1; i < 26; i++){SetPos(56, i);wprintf(L"%lc", L'□');}
}
我们也可以用宏定义将 L'□' 替换
#define WALL L'□'
(3)初始化蛇
void InitSnake(Snake *ps) // 初始化蛇
{SnakeNode *cur = ps->pSnake = NULL;for (int i = 0; i < 5; i++){cur = (SnakeNode *)malloc(sizeof(SnakeNode));if (cur == NULL){perror("InitSnake:malloc fail");return;}cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;if (ps->pSnake == NULL)ps->pSnake = cur;else{cur->next = ps->pSnake;ps->pSnake = cur;}}while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->Food = NULL;ps->SleepTime = 200;ps->Score = 0;ps->FoodScore = 10;ps->Status = RUN;ps->Dir = RIGHT;
}
这里的蛇身和蛇的初始位置也用了宏定义
#define BODY L'●'
//蛇的初始位置
#define POS_X 24
#define POS_Y 5
(4)生成食物
void CreateFood(Snake *ps) // 生成食物
{int x = 0;int y = 0;SnakeNode *cur = ps->pSnake;
again:do{x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 == 1);while (cur){if (cur->x == x || cur->y == y){goto again;break;}cur = cur->next;}ps->Food = (SnakeNode *)malloc(sizeof(SnakeNode));if (ps->Food == NULL){perror("CreateFood:malloc fail");return;}ps->Food->x = x;ps->Food->y = y;SetPos(x, y);wprintf(L"%lc", FOOD);
}
这里的食物也用了宏定义
#define FOOD L'★'
2.2 游戏运行中
这一部分需要包含分数等信息的打印和按键输入的判定等功能
这里将按键输入的判断封装为了宏
#define KEY_PRESS(VK) ((GetAsyncKeyState(VK) & 0x1) ? 1 : 0)
GetAsyncKeyState的返回值是short类型,在上一次调用完该函数后,如果返回的16位的short数据中最高位是1,说明按键的状态为按下,最高位是0则为抬起
void GameRun(Snake* ps)
{PrintHelpInfo();//打印教程do{//打印信息SetPos(60, 10);printf("当前得分:%2d", ps->Score);SetPos(60, 11);printf("当前速度:%3d", (400 - ps->SleepTime) / 40);SetPos(60, 12);printf("每个食物得分:%2d", ps->FoodScore);//判断按键if (KEY_PRESS(VK_UP) && ps->Dir != DOWN){ps->Dir = UP;}if (KEY_PRESS(VK_DOWN) && ps->Dir != UP){ps->Dir = DOWN;}if (KEY_PRESS(VK_LEFT) && ps->Dir != RIGHT){ps->Dir = LEFT;}if (KEY_PRESS(VK_RIGHT) && ps->Dir != LEFT){ps->Dir = RIGHT;}if (KEY_PRESS(VK_ESCAPE)){ps->Status = ESC;break;}if (KEY_PRESS(VK_SPACE)){pause();}if (KEY_PRESS(VK_F3)){if (ps->SleepTime > 40){ps->SleepTime -= 40;ps->FoodScore += 2;}}if (KEY_PRESS(VK_F4)){if (ps->FoodScore > 2){ps->SleepTime += 40;ps->FoodScore -= 2;}}Sleep(ps->SleepTime);//蛇身移动SnakeMove(ps);} while (ps->Status == RUN);
}
(1)打印教程
void PrintHelpInfo() // 打印教程
{SetPos(60, 16);printf("请按空格键开始游戏");SetPos(60, 17);printf("不能撞到墙上或者撞到自己");SetPos(60, 18);printf("用 ↑.↓.←.→ 控制蛇的行动");SetPos(60, 19);printf("F3为加速,F4为减速");SetPos(60, 20);printf("ESC:退出游戏 space:暂停游戏");
}
效果如下
(2)暂停游戏
void pause() // 暂停游戏
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE)){break;}}
}
(3)蛇身移动
void SnakeMove(Snake *ps) // 蛇身移动
{SnakeNode *next = (SnakeNode *)malloc(sizeof(SnakeNode));if (next == NULL){perror("SnakeMove:malloc fail");return;}switch (ps->Dir){case UP:next->x = ps->pSnake->x;next->y = ps->pSnake->y - 1;break;case DOWN:next->x = ps->pSnake->x;next->y = ps->pSnake->y + 1;break;case LEFT:next->x = ps->pSnake->x - 2;next->y = ps->pSnake->y;break;case RIGHT:next->x = ps->pSnake->x + 2;next->y = ps->pSnake->y;break;}if (next->x == ps->Food->x && next->y == ps->Food->y)EatFood(ps, next);elseNotEatFood(ps, next);KillByWall(ps);KillBySelf(ps);
}
(4)移动后吃到食物的情况
void EatFood(Snake *ps, SnakeNode *next) // 移动后吃到食物
{next->next = ps->pSnake;ps->pSnake = next;SetPos(next->x, next->y);wprintf(L"%lc", BODY);ps->Score += ps->FoodScore;free(ps->Food);ps->Food = NULL;CreateFood(ps);
}
(5)移动后没吃到食物的情况
void NotEatFood(Snake *ps, SnakeNode *next) // 移动后没吃到食物
{next->next = ps->pSnake;ps->pSnake = next;SnakeNode *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; // 不置空会出现问题
}
(6)检测是否撞墙
void KillByWall(Snake *ps) // 检测是否撞墙
{if (ps->pSnake->x == 0 ||ps->pSnake->x == 56 ||ps->pSnake->y == 0 ||ps->pSnake->y == 25){ps->Status = KILL_BY_WALL;}
}
(7)检测是否撞到自己
void KillBySelf(Snake *ps) // 检测是否撞到自己
{SnakeNode *cur = ps->pSnake->next;while (cur){if (ps->pSnake->x == cur->x && ps->pSnake->y == cur->y){ps->Status = KILL_BY_SELF;}cur = cur->next;}
}
2.3 游戏结束后
void GameEnd(Snake *ps)
{SetPos(24, 12);switch (ps->Status){case KILL_BY_SELF:printf("你撞到了自己");break;case KILL_BY_WALL:printf("你撞到墙了");break;case ESC:printf("游戏退出中...");break;}SnakeNode *cur = ps->pSnake;while (ps->pSnake){ps->pSnake = ps->pSnake->next;free(cur);cur = ps->pSnake;}
}
2.4 完整代码
#include "snake.h"void SetPos(short x, short y)//设置光标坐标
{COORD pos = { x,y };HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorPosition(handle, pos);
}void WelcomeToGame()//欢迎界面
{SetPos(45, 10);printf("欢迎来到贪吃蛇小游戏");SetPos(45, 15);system("pause");system("cls");SetPos(35, 10);printf("用 ↑.↓.←.→ 控制蛇的行动,F3为加速,F4为减速");SetPos(35, 11);printf("加速能得到更多的分数");SetPos(45, 15);system("pause");system("cls");
}void CreateMap()//创建地图
{SetPos(0, 0);int i = 0;for (i = 0; i < 58; i += 2){SetPos(i, 0);wprintf(L"%lc", WALL);}for (i = 0; i < 58; i += 2){SetPos(i, 26);wprintf(L"%lc", WALL);}for (i = 1; i < 26; i++){SetPos(0, i);wprintf(L"%lc", WALL);}for (i = 1; i < 26; i++){SetPos(56, i);wprintf(L"%lc", WALL);}
}void InitSnake(Snake* ps)//初始化蛇
{SnakeNode* cur = ps->pSnake = NULL;for (int i = 0; i < 5; i++){cur = (SnakeNode*)malloc(sizeof(SnakeNode));if (cur == NULL){perror("InitSnake:malloc fail");return;}cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;if (ps->pSnake == NULL)ps->pSnake = cur;else{cur->next = ps->pSnake;ps->pSnake = cur;}}while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->Food = NULL;ps->SleepTime = 200;ps->Score = 0;ps->FoodScore = 10;ps->Status = RUN;ps->Dir = RIGHT;
}void CreateFood(Snake* ps)//生成食物
{int x = 0;int y = 0;SnakeNode* cur = ps->pSnake;
again:do {x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 == 1);while (cur){if (cur->x == x || cur->y == y){goto again;break;}cur = cur->next;}ps->Food = (SnakeNode*)malloc(sizeof(SnakeNode));if (ps->Food == NULL){perror("CreateFood:malloc fail");return;}ps->Food->x = x;ps->Food->y = y;SetPos(x, y);wprintf(L"%lc", FOOD);
}void GameStart(Snake* ps)
{system("mode con cols=100 lines=30");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 PrintHelpInfo()//打印教程
{SetPos(60, 16);printf("请按空格键开始游戏");SetPos(60, 17);printf("不能撞到墙上或者撞到自己");SetPos(60, 18);printf("用 ↑.↓.←.→ 控制蛇的行动");SetPos(60, 19);printf("F3为加速,F4为减速");SetPos(60, 20);printf("ESC:退出游戏 space:暂停游戏");
}void pause()//暂停游戏
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE)){break;}}
}void EatFood(Snake* ps, SnakeNode* next)//移动后正好吃到食物
{next->next = ps->pSnake;ps->pSnake = next;SetPos(next->x, next->y);wprintf(L"%lc", BODY);ps->Score += ps->FoodScore;free(ps->Food);ps->Food = NULL;CreateFood(ps);
}void NotEatFood(Snake* ps, SnakeNode* next)//移动后没吃到食物
{next->next = ps->pSnake;ps->pSnake = next;SnakeNode* 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(Snake* 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(Snake* ps)//检测是否撞到自己
{SnakeNode* cur = ps->pSnake->next;while (cur){if (ps->pSnake->x == cur->x && ps->pSnake->y == cur->y){ps->Status = KILL_BY_SELF;}cur = cur->next;}
}void SnakeMove(Snake* ps)//蛇身移动
{SnakeNode* next = (SnakeNode*)malloc(sizeof(SnakeNode));if (next == NULL){perror("SnakeMove:malloc fail");return;}switch (ps->Dir){case UP:next->x = ps->pSnake->x;next->y = ps->pSnake->y - 1;break;case DOWN:next->x = ps->pSnake->x;next->y = ps->pSnake->y + 1;break;case LEFT:next->x = ps->pSnake->x - 2;next->y = ps->pSnake->y;break;case RIGHT:next->x = ps->pSnake->x + 2;next->y = ps->pSnake->y;break;}if (next->x == ps->Food->x && next->y == ps->Food->y)EatFood(ps, next);elseNotEatFood(ps, next);KillByWall(ps);KillBySelf(ps);
}void GameRun(Snake* ps)
{PrintHelpInfo();do{//打印信息SetPos(60, 10);printf("当前得分:%2d", ps->Score);SetPos(60, 11);printf("当前速度:%3d", (400 - ps->SleepTime) / 40);SetPos(60, 12);printf("每个食物得分:%2d", ps->FoodScore);//判断按键if (KEY_PRESS(VK_UP) && ps->Dir != DOWN){ps->Dir = UP;}if (KEY_PRESS(VK_DOWN) && ps->Dir != UP){ps->Dir = DOWN;}if (KEY_PRESS(VK_LEFT) && ps->Dir != RIGHT){ps->Dir = LEFT;}if (KEY_PRESS(VK_RIGHT) && ps->Dir != LEFT){ps->Dir = RIGHT;}if (KEY_PRESS(VK_ESCAPE)){ps->Status = ESC;break;}if (KEY_PRESS(VK_SPACE)){pause();}if (KEY_PRESS(VK_F3)){if (ps->SleepTime > 40){ps->SleepTime -= 40;ps->FoodScore += 2;}}if (KEY_PRESS(VK_F4)){if (ps->FoodScore > 2){ps->SleepTime += 40;ps->FoodScore -= 2;}}Sleep(ps->SleepTime);//蛇身移动SnakeMove(ps);} while (ps->Status == RUN);
}void GameEnd(Snake* ps)
{SetPos(24, 12);switch (ps->Status){case KILL_BY_SELF:printf("你撞到了自己");break;case KILL_BY_WALL:printf("你撞到墙了");break;case ESC:printf("游戏退出中...");break;}SnakeNode* cur = ps->pSnake;while (ps->pSnake){ps->pSnake = ps->pSnake->next;free(cur);cur = ps->pSnake;}
}
四、test.c
#include "snake.h"void Test()
{srand((unsigned int)time(NULL));char ch = 0;do{Snake snake;GameStart(&snake);GameRun(&snake);GameEnd(&snake);if (snake.Status == ESC)break;SetPos(24, 13);printf("再来一局吗?(Y/N):");scanf(" %c", &ch);} while (ch == 'Y' || ch == 'y');SetPos(0, 27);
}int main()
{setlocale(LC_ALL, "chs");Test();return 0;
}
相关文章:

基于链表实现贪吃蛇游戏
本文中,我们将使用链表和一些Win32 API的知识来实现贪吃蛇小游戏 一、功能 (1)游戏载入界面 (2)地图的绘制 (3)蛇身的移动和变长 (4)食物的生成 (5&…...

Python网络爬虫实战——实验6:Python实现js逆向与加解密
【实验内容】 本实验主要介绍在数据采集过程中对js代码进行分析从而对加密字段进行解密。 【实验目的】 1、理解js逆向工程的概念 2、学会逆向工程中的加解密分析 【实验步骤】 步骤1 理解js逆向工程的概念 步骤2 学会逆向工程中的加解密分析 步骤3 采集广东政府采购网 步…...

【python】使用aiohttp库编写一个简单的异步服务器
1. aiohttp介绍 aiohttp 是一个用于编写异步 HTTP 客户端和服务器的 Python 库。它建立在 Python 的 asyncio 库之上,提供了一种方便的方式来处理异步请求和响应。 官网地址:Welcome to AIOHTTP — aiohttp 3.9.1 documentation 以下是 aiohttp 的一些…...

新手使用代理IP接入代码教程
“实现匿名访问与数据保护在当今互联网高速发展的时代,网络安全和隐私保护成为了越来越重要的议题。代理IP可以隐藏用户的真实IP地址,从而实现匿名访问。为了保护用户的隐私和数据安全,许多网站和应用程序都采用了代理IP技术。” 一、代理IP的…...

JVM问题排查手册
三万字长文:JVM内存问题排查Cookbook 一、Heap快照 # jmap命令保存整个Java堆(在你dump的时间不是事故发生点的时候尤其推荐) jmap -dump:formatb,fileheap.bin <pid> # jmap命令只保存Java堆中的存活对象, 包含live选项,…...

前端canvas项目实战——简历制作网站(三)——右侧属性栏(线条宽度样式)
目录 前言一、效果展示二、实现步骤1. 实现线条宽度(strokeWidth)的属性模块2. 实线线条样式(strokeDashArray)的属性模块3. 意料之外的“联动” 三、Show u the code后记 前言 上一篇博文中,我们初步实现了右侧属性栏…...

字节跳动二面经典题目
前言 语论即为「语兴式论语」,以语录体及对话的形式,沉淀球友实际工作学习中存在的疑难杂症解答,希望能够更好的帮助到球友和粉丝。欢迎关注公众号:语数 本期投稿 本期语数精选来源于球友应对字节跳动二面时候的场景问题 数仓工程…...

微搭低代码从入门到精通01应用介绍
目录 1 学习路线图2 应用介绍3 编辑器介绍总结 低代码的概念于2014年由 Forrester 首次正式提出。其将低代码定义为:能够以“最少的手写代码”和设置快速开发应用、配置和部署业务应用程序。 不同应用厂商的解法不一样,Gartner评估了400多款低代码/无代码…...

论文阅读《thanking frequency fordeepfake detection》
项目链接:https://github.com/yyk-wew/F3Net 这篇论文从频域的角度出发,提出了频域感知模型用于deepfake检测的模型 整体架构图: 1.FAD: 频域感知分解,其实就是利用DCT变换,将空间域转换为频域ÿ…...

ArcgisForJs快速入门
文章目录 0.引言1.前端代码编辑工具2.使用ArcgisForJs创建一个简单应用3.切片地图服务图层4.动态地图服务图层5.地图事件 0.引言 ArcGIS API for JavaScript是一款由Esri公司开发的用于创建WebGIS应用的JavaScript库。它允许开发者通过调用ArcGIS Server的REST API,…...

【解决方法】git pull报错ssh: connect to host github.com port 22: Connection timed out
问题 git pull ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository.解决方法 在C:\Users\username.ssh文件夹下新建config文件,填入以下文本(如有则直接在文件最后一行新增)&am…...

30天精通Nodejs--第三十天:项目实战-物联网应用
目录 引言架构设计编码创建项目数据服务模拟设备消息接收并保存设备数据后端接口项目启动及接口测试项目启动测试源码地址结语引言 在之前的一系列文章中,我们已系统性地探讨了诸多Node.js相关的技术要点与理论背景。随着知识体系的铺垫到位,我们现在步入了实战环节。接下来…...

java 社区资源管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 java Web社区资源管系统是一套完善的java web信息管理系统 ,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.…...

网络编程套接字(Socket)
为什么需要网络编程??? -丰富的网络资源 每天你在b站上刷着喜欢的up主的视频,实质是通过网络,获取到网络上的一个视频资源 与本地打开文件类似,只是视频文件这个资源来源是网络 所谓的网络编程,其实就是从网络上获取各种数据资源 什么是网络编程?? 网络编程,指的是网络…...

C语言第十一弹---函数(下)
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 函数 1、嵌套调用和链式访问 1.1、嵌套调用 1.2、链式访问 2、函数的声明和定义 2.1、单个文件 2.2、多个文件 2.3、static 和 extern 2.3.1、static…...

Unity读书系列《Unity3D游戏开发》——拓展编辑器(一)
文章目录 前言一、扩展Project视图1、右键扩展菜单(Asset)2、监听事件3、拓展布局 二、扩展Hierarchy视图1、拓展菜单(GameObject)2、拓展布局3、重写菜单 三、扩展Inspector视图1、扩展原生组件2、扩展继承组件 四、扩展Scene视图…...

【Git】项目管理笔记
文章目录 本地电脑初始化docker报错.gitignoregit loggit resetgit statusgit ls-filesgit rm -r -f --cached拉取仓库文件更新本地的项目报错处理! [rejected] master -> master (fetch first)gitgitee.com: Permission denied (publickey).error: remote origin already e…...

中文词性标注工具pkuseg例子(运行结果,不太好)
pkuseg_demo.md pkuseg 预训练模型 预训练模型science 安装 pip3 install pkuseg cd /rot/pkuseg_home/model/wget https://github.com/lancopku/pkuseg-python/releases/download/v0.0.25/science.zip uzip science.zip -d ./science/ ls /rot/pkuseg_home/model/science/…...

获取URL参数:split方法、URLSearchParams方法示例
在JavaScript中,可以使用多种方法来获取URL参数,其中常用的方法有split()和URLSearchParams()。 使用split()方法获取URL参数: split()方法将字符串分割成数组。可以使用split()方法将URL分割成协议、主机、路径和查询字符串等部分。然后可…...

SparkSql---用户自定义函数UDFUDAF
文章目录 1.UDF2.UDAF2.1 UDF函数实现原理2.2需求:计算用户平均年龄2.2.1 使用RDD实现2.2.2 使用UDAF弱类型实现2.2.3 使用UDAF强类型实现 1.UDF 用户可以通过 spark.udf 功能添加自定义函数,实现自定义功能。 如:实现需求在用户name前加上"Name:…...

系统架构15 - 软件工程(3)
软件过程模型 瀑布模型特点缺点 原型化模型特点两个阶段不同类型注意 螺旋模型V 模型特点 增量模型特点 喷泉模型基于构件的开发模型(CBSD)形式化方法模型敏捷模型特点“适应性” (adaptive) 而非“预设性” (predictive)“面向人的” (People-oriented) 而非“面向过程的” (P…...

两个近期的计算机领域国际学术会议(软件工程、计算机安全):欢迎投稿
近期,受邀担任两个国际学术会议的Special session共同主席及程序委员会成员(TPC member),欢迎广大学界同行踊跃投稿,分享最新研究成果。期待这个夏天能够在夏威夷檀香山或者加利福尼亚圣荷西与各位学者深入交流。 SERA…...

(二十一)Flask之上下文管理第二篇(细细扣一遍源码)
每篇前言: 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 🔥🔥本文已收录于Flask框架从入门到实战专栏:《Flask框架从入…...

Java项目:基于SSM框架实现的企业员工岗前培训管理系统(ssm+B/S架构+源码+数据库+毕业论文)
一、项目简介 本项目是一套ssm821基于ssm框架实现的企业员工岗前培训管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格…...

深入了解Redis:选择适用于你的场景的持久化方案
自然语言处理的发展 文章目录 自然语言处理的发展强烈推荐前言:Redis提供了几种主要的持久化方案:RDB快照持久化:工作原理: AOF日志文件持久化:混合持久化: 总结强烈推荐专栏集锦写在最后 强烈推荐 前些天…...

【Git配置代理】Failed to connect to github.com port 443 问题解决方法
前言: 在学习代码审计时,有时会需要使用git去拉取代码,然后就出现了如下错误 看过网上很多解决方法,觉得问题的关键还是因为命令行在拉取/推送代码时并没有使用VPN进行代理。 解决办法 : 配置http代理:…...

python提取word文档内容的示例
一、微软Word历史、背景: Word 的特异功能就是把那些应该写成简单的 TXT 或 PDF 格式的文件,变成了既大又慢且难以打开的怪兽,它们经常在系统切换和版本切换中出现格式不兼容,而且因为某些原因在文件内容已经定稿后仍处于可编辑的…...

MarkDown快速入门-以Obsidian编辑器为例
直接上图,左右对应。 首先是基础语法。 # 标题,几个就代表几级标题;* 单个是序号,两个在一起就是斜体;- [ ] 代表任务,注意其中的空格; 然后是表格按钮代码 | 使用中竖线代表表格,…...

【计算机网络】协议,电路交换,分组交换
定义了在两个或多个通信实体之间交换的报文格式和次序,以及报文发送和/或接收一个报文或其他事件所采取的动作.网络边缘: 端系统 (因为处在因特网的边缘) 主机 端系统 客户 client服务器 server今天大部分服务器都属于大型数据中心(data center)接入网(access network) 指将端…...

加速应用开发:低代码云SaaS和源码交付模式如何选
随着数字化转型的加速,企业对于快速开发和交付高质量应用的需求也越来越迫切。为了满足这一需求,开发者们开始探索采用低代码平台进行软件开发工作,以加速应用开发过程。 目前,市场上的低代码产品众多,但基本可分为简单…...