C语言实现电子秒表

Maleah ·
更新时间:2024-09-20
· 383 次阅读

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

实现思路

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

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)                     }                     else                         sec_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)             }             else                 tv_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语言

需要 登录 后方可回复, 如果你还没有账号请 注册新账号