秒表是我们生活中常见的计时工具,特别是在运动会等比赛中,今天我就来写一个简单的电子秒表。

文章目录

  • 实现思路
  • 简易版本
  • 高级版本

实现思路

这里简单介绍一下我的实现思路:

  1. 简单版:简单版本只实现了单次计时功能,即每次开启程序后就开始计时,如果按下键盘任意键,就结束计时,计时通过Sleep(1000)延时实现,每过1秒,计数值(总秒数)cnt加1,打印时,将总秒数cnt转换成时分秒进行显示。【Sleep()函数并不准确,只能实现粗略延时】
  2. 高级版:实现毫秒级计时,可重复计时(暂停、清零),计时使用gettimeofday()函数,用来获取系统的秒数和毫秒数,将计时开始和计时暂停的秒数相减,即可获得计时期间的秒数。细节请看代码部分。

简易版本

#include <stdio.h>
#include <conio.h>              //kbhit()/_kbhit()
#include <Windows.h>            //Sleep(ms)int main()
{int hour = 0, min = 0, sec = 0;int cnt = 0;printf("按任意键停止计时\n");while(!_kbhit())            //任意键退出循环(结束计时){hour = cnt / 3600;      //获取计时小时数min = cnt / 60;          //获取计时分钟数sec = cnt % 60;         //获取计时秒数printf("  %02d:%02d:%02d\r", hour, min, sec);Sleep(1000);            //1s延时cnt++;}printf("\n程序退出\n");return 0;
}

运行效果:

高级版本

代码可能一般,但至少功能已经实现,仅供参考
下面给出几个注释的解释

  • 计时初始时间指的是开始计时继续计时时的系统时间(第一次暂停后,如果继续计时,此时的系统时间即为新的计时初始时间
  • 当前累计计时时长指的是从开始计时当前时刻的时间差,即真正的有效计时时长
  • 总累计计时时长指的是计时初始时间之前的计时时间,这个值只有在计时暂停时才进行更新(如第一次暂停时,总累计计时时长 = 第一次暂停的系统时间 - 开始计时时的系统时间;第二次暂停时,总累计计时长 = 总累计计时时长 + 第二次在暂停的系统时间 - 上次继续计时时的系统时间…)
#include <stdio.h>
#include <conio.h>                 //kbhit()/_kbhit() getch()
#include <Windows.h>               //Sleep(ms)
#include <sys/time.h>              //struct timeval
#include <unistd.h>                //struct timeval/******************************************************************************* @brief       获取系统当前秒数和毫秒(1970-1-1 0:0:0到现在)* @param tv    timeval结构体变量* @param tv_s  返回的秒数* @param tv_ms 返回的毫秒数******************************************************************************/
void Get_Current_Timeval(struct timeval *tv, long *tv_s, long *tv_ms)
{gettimeofday(tv,NULL);      //获取1970-1-1到现在的时间保存到timeval变量*tv_s = tv->tv_sec;         //获取秒*tv_ms = tv->tv_usec / 1000;//获取毫秒
}/******************************************************************************* @brief            获取两个timeval成员的差值,通过tv_s_diff和tv_ms_diff返回* @param tv_s_cur   当前系统时间秒数* @param tv_ms_cur  当前系统时间毫秒数* @param tv_s_old   计时初始时间(s)* @param tv_ms_old  计时初始时间(ms)* @param tv_s_diff  秒数的差值* @param tv_ms_diff 毫秒的差值******************************************************************************/
void Get_Diff_Timeval(long tv_s_cur, long tv_ms_cur,\long tv_s_old, long tv_ms_old,\long *tv_s_diff, long *tv_ms_diff)
{if(tv_ms_cur < tv_ms_old){*tv_ms_diff = tv_ms_cur + 1000 - tv_ms_old;  //获取这段时间的毫秒数*tv_s_diff = tv_s_cur - tv_s_old - 1; //获取这段时间的秒数(自上次暂停或自初始时间)}else{*tv_ms_diff = tv_ms_cur - tv_ms_old;  //获取这段时间的毫秒数(自上次暂停或自初始时间)*tv_s_diff = tv_s_cur - tv_s_old;     //获取这段时间的秒数(自上次暂停或自初始时间)}
}/******************************************************************************* 主函数* ****************************************************************************/
int main(void)
{struct timeval tv;long tv_s_cur = 0, tv_ms_cur = 0;   //当前系统时间long tv_s_old = 0, tv_ms_old = 0;   //计时初始时间long tv_s_diff = 0, tv_ms_diff = 0; //存放时间的差值int sec_cnt = 0, msec_cnt = 0;      //当前累计计时时长int hour = 0, min = 0, sec = 0, msec = 0;int timer_step = 0;                 //计时步骤 0:未开始,//1:开始,2:暂停char key = 0;/**************** 菜单打印 ****************/printf("================================\n"); //菜单printf("| 空格:开始/暂停 R:清零 Q:退出 |\n");printf("================================\n");printf("\t%02d:%02d:%02d %02d\r", 0, 0, 0, 0);while(1){/**************** 键盘按键扫描+操作 ****************/key = 0;if(_kbhit())                      //检测到按键按下key = getch();                //读取按键switch(key){case ' ':                     //按空格键开始/暂停计时if(timer_step == 0)       //如果还未开启计时{//获取当前秒和毫秒作为计时初始时间Get_Current_Timeval(&tv, &tv_s_old, &tv_ms_old);timer_step = 1;       //开始计时}else if(timer_step == 1)  //如果正在计时{timer_step = 2;       //暂停计时//获取当前秒和毫秒Get_Current_Timeval(&tv, &tv_s_cur, &tv_ms_cur);//获取当前系统时间与计时初始时间的差值Get_Diff_Timeval(tv_s_cur, tv_ms_cur, tv_s_old,\tv_ms_old, &tv_s_diff, &tv_ms_diff);msec_cnt += tv_ms_diff;       //更新总累计计时时长(ms)if(msec_cnt >= 1000){msec_cnt -= 1000;sec_cnt += tv_s_diff + 1; //更新总累计计时时长(s)}elsesec_cnt += tv_s_diff;}else if(timer_step == 2){timer_step = 1;                //继续计时//获取当前秒和毫秒Get_Current_Timeval(&tv, &tv_s_cur, &tv_ms_cur);tv_s_old = tv_s_cur;           //更新计时初始时间(s)tv_ms_old = tv_ms_cur;         //更新计时初始时间(ms)}break;case 'r':                     //按r/R清零计时时间case 'R':sec_cnt = msec_cnt = 0;   //总累计计时值清零tv_s_old = tv_s_cur;      //更新计时初始时间(s)tv_ms_old = tv_ms_cur;    //更新计时初始时间(ms)timer_step = 0;           //回到步骤0(未开始计时)printf("\t%02d:%02d:%02d %02d\r", 0, 0, 0, 0);break;case 'q':case 'Q': printf("程序退出\n");return 0;}/**************** 计时操作 ****************/if(timer_step == 1){//获取当前秒和毫秒Get_Current_Timeval(&tv, &tv_s_cur, &tv_ms_cur);//获取当前系统时间与计时初始时间的差值Get_Diff_Timeval(tv_s_cur, tv_ms_cur, tv_s_old,\tv_ms_old, &tv_s_diff, &tv_ms_diff);tv_ms_diff += msec_cnt;          //当前累计计时时长(ms)if(tv_ms_diff >= 1000){tv_ms_diff -= 1000;tv_s_diff += sec_cnt + 1;    //当前累计计时时长(s)}elsetv_s_diff += sec_cnt;hour = tv_s_diff / 3600;         //获取计时小时数min = tv_s_diff /60;             //获取计时分钟数sec = tv_s_diff % 60;            //获取计时秒数msec = tv_ms_diff / 10;          //获取毫秒(单位10ms)//打印当前累计计时时长printf("\t%02d:%02d:%02d %02d\r", hour, min, sec, msec);}Sleep(10);                            //10ms延时,防止打印太快导致显示效果不佳}return 0;
}

运行效果:

C语言小项目——电子秒表(毫秒级)相关推荐

  1. c语言为什么要建项目,一个C语言小项目为什么都说牛逼

    原标题:一个C语言小项目为什么都说牛逼 意在鼓励C语言学者.更有兴趣,学习更富有创业和乐趣! 推荐加学习交流群:658807522 可以在一起学习交流,既是参赛选手,又是学者,也可以先学习再参赛,反正 ...

  2. C语言小项目——走迷宫

    C语言小项目--走迷宫 设计方向: 1.定义二维字符数组作为迷宫 2.定义变量记录老鼠的位置 3.判定移动后位置的变化 4.记录游戏时长 5.判定到达终点的条件 总体设计: 1.用不同字符代表墙.老鼠 ...

  3. C语言小项目之“究极无敌螺旋丸极爆炸狂拽炫酷五彩棒的”通讯录之*派小猩*作品

    C语言小项目之"究极无敌螺旋丸极爆炸狂拽炫酷五彩棒的"通讯录之派小猩作品 项目概述 基于C语言开发一个多功能的通讯录 功能目录 1.增加 2.删除 3.查找 4.修改 5.显示 6 ...

  4. C语言小项目——通讯录的存储系统(静态版,动态版,文件版)

    目录 前言 一.总体设计框架 二.三种通讯录的功能阐述 三.静态通讯录 1.结构体设计 2.初始化通讯录 3.增加联系人的信息 4.删除联系人的信息 5.查找指定联系人并打印 6.修改联系人的信息 7 ...

  5. 嵌入式培训经验分享——C语言小项目(五子棋)

    在学习了C语言的基本语法之后,我们可以尝试着来做一个小小的项目,下面是我尝试着做的一个小项目-----五子棋,分享给大家,功能不太完善,多多指教,里面没有用到指针的知识点. #include < ...

  6. C语言小项目Conway‘s_Game_of_Life

    这是我C语言的一个小项目,如有Bug请指出. 用C语言来实现Conway's_Game_of_Life 规则: 细胞有存活或死亡两种状态,与自身周围的八个细胞互动 细胞周围的存活细胞 == 2个时,该 ...

  7. C语言小项目之猜数字

    学习完c语言循环.选择内容,我们对c语言有个初步的认识了,让我们来实现一个小项目吧!!! 1.猜数字小项目分析: 我们利用c语言制造出随机数来猜,在只知道范围的前提下我们无非有以下三种可能,猜大了.猜 ...

  8. C语言小项目-《通讯录》(超详细讲解)

    加油加油!!! 文章目录 前言 一:静态库通讯录 1:通讯录介绍 1.1代码主体框架的介绍 1.2 要实现的功能 2:通讯录实现 2.1 通讯录的外部封装 2.1 创建通讯录 2.2 初始化通讯录 2 ...

  9. 学习笔记10-C语言-小项目-五子棋

    小项目: 需要的数据 1.定义棋盘的二维数组 2.定义变量用于记录下棋的坐标 3.定义角色 @ 黑棋 O 白棋 * 空位业务逻辑: 是否需要对数据初始化 for(;;) {1.清屏.显示棋盘2.落子坐 ...

  10. C语言小项目实践——日历程序

    完整代码包已经上传至我的down,修改请保留原作者注释 http://download.csdn.net/detail/xuptacm/9835030 炫迈日历计划研究报告 1.引言 日常生活中我们往 ...

最新文章

  1. CART树 python小样例
  2. 看完这篇!Linux网络基础知识通关!
  3. Android 单击+双击+短按+长按 逻辑
  4. VUE : 双重 for 循环写法、table 解析任意 list 、万能表格组件、解析一维数组、动态生成 table 所有数据
  5. 方法论:如何从0到1搭建一套完整的邀请体系
  6. Eureka获取注册信息
  7. nvm use切换node版本,但是切换后没有*号
  8. neo4j 节点与关系
  9. linux shell解析1
  10. 多表查询, 聚集查询和分组查询
  11. c#教程与视频教程类专题资料免费下载整理合集
  12. 关于metasploit的一些架构目录
  13. 时间片轮转调度算法(Java)
  14. 根据后缀名/扩展名获取content-type/Mime类型
  15. SecureCRT/FX的破解软件注册机被系统自动删除解决办法
  16. HDU3404POJ3533(Nim积摸版)
  17. phhphphphphphphp转自 细雪之舞 专注DEV
  18. Bibexcel 与 Pajek 基本分析
  19. 【矩阵论】2. 矩阵分解——SVD
  20. python爬虫代理ip_Python爬虫如何获取代理ip及ip验证?

热门文章

  1. LODOP打印控件简单示例
  2. tensorflow的pb文件转化为pbtxt
  3. 小区停车管理系统(SQL,JDBC)
  4. Windows官网下载Win10原版镜像文件
  5. 关于H3C-WAP712C AP的胖瘦切换说明
  6. CIC滤波器设计原理总结
  7. VBA编程之ODBC连接数据库
  8. mathtype安装教程
  9. 计算机应用基础好不好考,计算机应用基础好考么
  10. 农行2021软件开发笔试题