函数雪花算法_编程代码:⽤C语⾔来实现下雪效果,这个冬
天,雪花很美
前⾔
1.本⽂主要围绕 如何 在 控制台上 下起 ⼀场 只有⾃⼰能看见的雪
2.是个简易跨平台的,主要是C语⾔
3.动画 采⽤ 1s 40帧, 雪花具有 x轴速度和y轴速度
4.⽐较简单,可以给学⽣作为C语⾔结课作业吧.
正⽂
1.1 先简单处理跨平台
  本⽂写作动机,还是感谢⼀下⼤学的启蒙⽼师,让我知道了有条路叫做程序员,可以作为⼯作⽣存下去.那就上代码了.
⾸先代码定位 是 ⾯向 简单跨平台,⾄少让 gcc 和 vs 能够跑起来.
其实跨平台都是嚼, 说⽩了就是⼀些丑陋的宏. 真希望所有系统合⼆为⼀,采⽤统⼀的标准api 设计,但这是不可能的,就相当于很早之前的电视制式⼀样.
那么我们先看 围绕跨平台的宏
#include #include #include #include /** 时间 : 2015年12⽉26⽇11:43:22
* 描述 : 应该算过节吧,今天,写了个雪花特效 代码,
* *//** 清除屏幕的shell 命令/控制台命令,还有⼀些依赖平台的实现
* 如果定义了 __GNUC__ 就假定是 使⽤gcc 编译器,为Linux平台
* 否则 认为是 Window 平台*/#ifdefined(__GNUC__)//下⾯是依赖 Linux 实现#include #definesleep_ms(m) usleep(m *1000)//向上移动光标函数 Linuxstaticvoid__curup(int height)
{
inti = -1;
while(++i
printf("033[1A");//先回到上⼀⾏ }#else// 创建等待函数 1s 60 帧 相当于 16.7ms => 1帧, 我们取16ms// 咱么的这屏幕 推荐1s 25帧吧 40ms// 这⾥创建等待函数 以毫秒为单位 , 需要依赖操作系统实现#include #definesleep_ms(m) Sleep(m)//向上移动光标staticvoid__curup(int height)
{
COORD cr = {0,0};
// GetStdHandle(STD_OUTPUT_HANDLE) 获取屏幕对象, 设置光标
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cr);
}#endif/*__GNUC__ 跨平台的代码都很丑陋 */
⾸先是 sleep_ms 这个宏, 传⼊⼀个毫秒数,让操作系统等待.
对于__curup 实现的不好. 功能是 让 控制台当前光标移动到 上⾯的 height 位置,对于 window直接移动到第⼀⾏(0,0)位置.
上⾯⼀共⽤了 5个头⽂件 还是容易的代码. string.h 主要⽤的是 memset 函数, 让⼀段内存初始化,⽤0填充.
对于time.h 主要是为了 初始化时间种⼦,⽅便每次运⾏都不⼀样.
// 初始化随机数种⼦,改变雪花轨迹srand((unsigned)time(NULL));
1.2 再说主业务代码
这⾥程序员运⾏的主业务,先说⼀说这⾥⽤的数据结构 如下
// 定义初始屏幕的宽⾼像素宏#define_INT_WIDTH (100)#define_INT_HEIGHT (50)// 屏幕刷新帧的速率#define_INT_FRATE
(40)// 雪花飘落的速率,相对于 屏幕刷新帧 的倍数#define_INT_VSNOW (10)/** 错误处理宏,msg必须是""括起来的字符串常量
* __FILE__ : ⽂件全路径
* __func__ : 函数名
* __LINE__ : ⾏数⾏
fprintf作用* __VA_ARGS__ : 可变参数宏,
* ##表⽰直接连接, 例如 a##b <=> ab*/#definecerr(msg,...) fprintf(stderr, "
[%s:%s:%d]"msg"",__FILE__,__func__,__LINE__,##__VA_ARGS__);/** 屏幕结构体, 具有 宽⾼
* frate : 绘制⼀帧的周期, 单位是 毫秒
* width : 屏幕的宽,基于窗⼝的左上⾓(0,0)
* height : 屏幕的⾼
* pix : ⽤⼀维模拟⼆维 主要结构如下
* 0 0 0 1 0 0 1 0 1 0
* 0 1 0 1 0 1 0 1 2 0
* . . .
* => 0表⽰没像素, 1表⽰1个像素,2表⽰2个像素....*/struct screen {
intfrate;// 也可以⽤ unsigned 结构int width;
int height;
char*pix;
};
创建了⼀个绘图对象 struct screen 这⾥ 构建这个结构体的时候⽤了下⾯⼀个技巧
//后⾯是 为 scr->pix 分配的内存 width*heightscr =malloc(sizeof(structscreen) +sizeof(char)*width*height);
⼀次分配两个内存空间.下⾯是主要实现的api 对象
/** 创建⼀个 屏幕结构指针 返回
*
* int frate : 绘制⼀帧的周期
* int width : 屏幕宽度
* int height : 屏幕⾼度
* return : 指向屏幕结构的指针
* */structscreen* screen_create(intfrate,intwidth,int height);/** 销毁⼀个 屏幕结构指针, 并为其置空
* struct screen** : 指向 屏幕结构指针的指针, ⼆级销毁⼀级的
* */voidscreen_destory(structscreen** pscr);/**
* 屏幕绘制函数,主要⽣成⼀个雪花效果
*
* struct screen* : 屏幕数据
* return : 0表⽰可以绘制了,1表⽰图案不变*/intscreen_draw_snow(structscreen* scr);/**
* 屏幕绘制动画效果, 绘制雪花动画
*
* struct screen* : 屏幕结构指针*/voidscreen_flash_snow(structscreen* scr);
创建销毁, 绘制⼀个雪花界⾯, 绘制雪花动画效果的api. 其实都很相似,⽤opengl 库, 主要让我们省略了需要单独和操作系统显⽰层打交道⼯作.
这⾥介绍⼀下,个⼈ ⼀个 简单避免 野指针的 的⽅法, 具体看下⾯实现
/** 销毁⼀个 屏幕结构指针, 并为其置空
* struct screen** : 指向 屏幕结构指针的指针, ⼆级销毁⼀级的
* */voidscreen_destory(structscreen** pscr)
{
if(NULL == pscr || NULL == *pscr)
return;
free(*pscr);
// 避免野指针*pscr = NULL;
}
在执⾏之后置空,因为C程序员对NULL⼀定要敏感,形成条件反射. 和⼤家开个玩笑 ,
请问 :
C 语⾔中, NULL , 0,'0',"0",false有什么异同 ?
欢迎同⾏,在招聘的时候问问,应聘初级开发⼯作者. 为什么C需要扣的那么细. 因为其它语⾔.你不明⽩是什么,
你可以⽤的很好. 但是C你写的代码,如果不知道会有怎样的结果,那么 线上就⼀⼤⽚服务器直接崩掉.⽽且还很难出问题所在. 因为C很简单,越简单就是越复杂.就越需要专业的维护⼈员.导致它成了'玩具'.
最后看⼀下 主业务
// 主函数,主业务在此运⾏intmain(intargc,char*argv[])
{
structscreen* scr = NULL;
//创建⼀个屏幕对象scr = screen_create(_INT_FRATE, _INT_WIDTH, _INT_HEIGHT);
if(NULL == scr)
exit(EXIT_FAILURE);
//绘制雪花动画 screen_flash_snow(scr);
//销毁这个屏幕对象screen_destory(&scr);
return0;
}
还是⾮常容易看懂的, 创建⼀个屏幕对象,绘制雪花效果.销毁屏幕对象.
1.3 说⼀写 接⼝的实现细节
先看⼏个简单的api 实现,创建和销魂代码如下,很直⽩.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。