C语言实现电子秒表

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

实现思路

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

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;
}

运行效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C语言实现基于控制台的电子时钟

    使用c语言制作一个控制台的电子时钟,供大家参考,具体内容如下 学习了c语言基本语法后,在学习了time.h的库文件,让我产生了想制作一款电子时钟的念头,那好就开始动手操作吧. 使用到下面这些技术: 首先必须先导入库 /***************** 实时数字时钟(和计算机系统时间关联) ************** #include <time.h>  -- 必须的时间函数头文件 time_t -- 时间类型(time.h 定义) struct tm -- 时间结构,time.h 定义如下

  • C语言绘制简单时钟小程序

    本文实例为大家分享了C语言绘制时钟小程序的具体代码,供大家参考,具体内容如下 先贴效果图给大家先看看 基本机制是通过获取系统的时钟去绘制图线进行展示 贴出代码 ,大家可以直接使用的 .程序我进一步的讲解 #include <graphics.h> #include <conio.h> #include <math.h> #include <time.h>   #define high 480 #define width 640 #define pi 3.14

  • C语言基于EasyX库实现有图形界面时钟

    本文实例为大家分享了C语言基于EasyX库实现有图形界面时钟的具体代码,供大家参考,具体内容如下 1.目标要求: 1.实现一个显示图像的时钟2.时间与本地时间一致 2.C语言代码: #include<graphics.h> //需要提前安装库函数EasyX,网上官网下载 #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<conio.h> #include<ma

  • C语言实现实时钟表

    本文实例为大家分享了C语言实现实时钟表的具体代码,供大家参考,具体内容如下 一.最终效果展示 效果图如下: 二.绘制静态秒针 代码如下: #include<graphics.h> #include<conio.h> #include<math.h> #define High 480 //游戏画面尺寸 #define Width 640 int main(void) {     initgraph(Width,High);//初始化绘图窗口     int center_

  • C语言基于EasyX库实现有图形界面钟表

    本文实例为大家分享了C语言基于EasyX库实现有图形界面钟表的具体代码,供大家参考,具体内容如下 1.目标要求: 实现一个显示图像的时钟 2.C语言代码: #include<graphics.h> //需要提前下载EasyX库哦 #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<conio.h> #include<math.h> #define High

  • C语言计算代码执行所耗CPU时钟周期

    该代码受乱序执行等影响, 需要sync LARGE_INTEGER _start = { 0 }, _end = { 0 }; __asm{ rdtsc mov dword ptr [_start.LowPart], eax mov dword ptr[_start.HighPart], edx } //your code here __asm{ rdtsc mov dword ptr [_end.LowPart], eax mov dword ptr[_end.HighPart], edx }

  • C语言基于EasyX绘制时钟

    本文实例为大家分享了C语言基于EasyX绘制时钟的具体代码,供大家参考,具体内容如下 函数说明: void line(     int x1,     int y1,     int x2,     int y2 ); 参数 x1直线的起始点的 x 坐标. y1直线的起始点的 y 坐标. x2直线的终止点的 x 坐标. y2直线的终止点的 y 坐标. 文件素材 源代码 #include <graphics.h> #include <conio.h> #include <mat

  • C语言实现电子时钟程序

    本文实例为大家分享了C语言实现电子时钟程序的具体代码,供大家参考,具体内容如下 Qt 里面运行 #include<windows.h> #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <time.h> typedef struct { int x; int y; }Point; time_t now; struct tm *pt, t1, t2; int pri

  • C语言实现电子秒表

    秒表是我们生活中常见的计时工具,特别是在运动会等比赛中,今天我就来写一个简单的电子秒表. 实现思路 这里简单介绍一下我的实现思路: 1.简单版:简单版本只实现了单次计时功能,即每次开启程序后就开始计时,如果按下键盘任意键,就结束计时,计时通过Sleep(1000)延时实现,每过1秒,计数值(总秒数)cnt加1,打印时,将总秒数cnt转换成时分秒进行显示.[Sleep()函数并不准确,只能实现粗略延时] 2.高级版:实现毫秒级计时,可重复计时(暂停.清零),计时使用gettimeofday()函数

  • C语言实现电子英汉词典系统

    本文实例为大家分享了C语言实现电子英汉词典系统的具体代码,供大家参考,具体内容如下 一.设计功能(文章仅供参考) a. 词条录入:即添加单词记录. b. 信息显示:将所有的单词按字母顺序显示. c. 词条修改:对已经输入的单词信息进行修改. d. 词条删除:删除某个单词记录. e. 单词查询: 输入单词英文拼写,输出该单词的中文释义. f. 信息保存:将单词信息保存到文件. g. 退出系统 二.功能展示 三.思维导图 四.程序源码 #include <stdio.h>    //引入库函数 #

  • C语言实现简单电子通讯录

    本文实例为大家分享了C语言实现电子通讯录的具体代码,供大家参考,具体内容如下 制作一个电子通讯录,通过该通讯录能录入好友ID号.姓名(英文).手 机号码,家庭住址,公司电话.** 原理:分成5个模块,将模块功能实现写入头文件中.主函数部分代码: 显示函数部分,在Markdown里对不齐,意思就这样,将就一下=.= /******************************************************************* 需求:制作一个电子通讯录,通过该通讯录能录入好

  • C++实现秒表功能

    本文实例为大家分享了C++实现秒表功能的具体代码,供大家参考,具体内容如下 抽象出CLOCK类来制作一个电子秒表,能够自动跳转 代码中有些陌生的库函数,顺便介绍一下: 1.system(“cls”)函数 system函数代表执行系统命令,system(“cls”)就是执行命令”清屏“的意思. #include <windows.h> system("cls");   2.setw()与setfill()函数 在C++中,setw(int n)用来控制输出间隔.setw()默

  • C语言实现简单电子通讯录(2)

    本文实例为大家分享了C语言实现简单电子通讯录的具体代码,供大家参考,具体内容如下 这两天学完系统调用和标准IO,之前的通讯录可以进行一些改进,将数据保存到文件中(图我这里就不发了). 原理:每次启动程序时先从预设文件中以只读的形式读取保存的通讯录信息,然后将读取到的信息导入到结构体中:每次执行退出时,先将预设文件以更新方式打开,并将文件中之前保存的信息清空,然后将结构体的数据保存到文件中去,再退出程序. 还有在文件写入时和读取时,先写入(读取)保存数据的总个数,让程序知道有多少数据要写入(读取)

  • C语言实现小型电子词典

    本文实例为大家分享了C语言实现小型词典系统,供大家参考,具体内容如下 1. 题目描述 用C语言编写一个小型词典,用户可以进行英译汉.汉译英.删除修改单词.添加单词等功能. 2.源代码 /* 小型词典系统 版本:0.9 作者:个快快 应用模型:文件增删改查 */ #include <stdio.h> #include <string.h> int worsNumber = 0; //单词数目 //---------------------- //定义结构体存储词典数据 //-----

  • [图]Flash+ASP实现电子互动地图在线标注功能

    于电子互动地图的信息量太大,完全可以通过客户端的广大操作者一同完成海量的标注工作,这样就必须实现在线标注的功能.而这样的功能单独依靠Flash本身是无法实现的.我们可以通过ASP.ASP.net.PHP等协助实现.在本例中,我们使用ASP来共同实现在线标注功能. 1.基本的通信过程 图1 SWF+XML与服务器的通信过程示意图点击看大图 图1展示的是本例中的通信过程示意.在 Flash 和数据库之间传递信息的服务器端脚本以 XML 格式读写数据. 可用 ActionScript 将 SWF 文件

  • 如何短时间内学好一门语言 shell脚本语言为例

    这里我分享的是学习计算机shell脚本语言的方法,可能你不是在软件行业,但我建议也看看,因为我并没有讲什么技术细节,主要分享的是提炼出的通用性方法,这是对学习任何东西都是有用的. 当然,如果你好奇心足够强的话,建议也可以按照下面的方法来尝试一下,因为科学家已经预测:以后的世界就是一个软件定义的世界,机器人和人工智能会非常普及,而支持它们运行的除了我们看得见的硬件,最关键的就是里面的软件. 所以,学会编程以后就不仅仅只是软件从业人员需要掌握的技能,任何人都可以掌握它,既可以用它来不断提高工作效率,

随机推荐