Windows控制台函数:计时器函数GetTickCount()

目录

什么是 GetTickCount?

什么是 GetTickCount64?

函数签名

怎么用它?

用 GetTickCount64 

用法

它们有什么区别?

跟其他计时方式对比

注意事项

更有趣的例子

什么是 GetTickCount?

GetTickCount 是一个 Windows API 函数,用来告诉你“从电脑开机到现在过去了多少毫秒”。它就像一个计时器,记录系统运行的时间,单位是毫秒(1 秒 = 1000 毫秒)。

想象你在玩游戏,想知道从游戏开始到现在过了多久,GetTickCount 就能帮你算这个时间。不过它是从系统启动开始计时的,不是从你程序开始。

什么是 GetTickCount64?

GetTickCount64 是 GetTickCount 的升级版,功能一样,也是返回系统运行的毫秒数,但它用 64 位整数表示,能记录更长时间。

  • 定义:

ULONGLONG GetTickCount64();
  • 返回值:一个 ULONGLONG 类型的值(64 位无符号整数)。

  • 特点:不会轻易溢出,支持 Vista 及以上系统。

函数签名

GetTickCount 的作用就是获取(Get)从系统启动以来经过的时间滴答数(Tick Count) 

  • Get:表示获取(获取某个值)。

  • Tick:指的是时钟滴答(tick),在计算机中,"tick" 代表系统启动后经过的时间单位(通常是毫秒)。

  • Count:表示数量,即计数的值。

它的定义很简单:

DWORD GetTickCount();
  • 没有参数:直接调用就行,不用传东西。

  • 返回值:一个 DWORD 类型的值(无符号整数),表示毫秒数。

怎么用它?

我们写个例子,看看系统运行了多久:

#include <windows.h>

int main() {
    // 获取当前毫秒数
    DWORD ticks = GetTickCount();

    // 输出
    HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
    if (screen == INVALID_HANDLE_VALUE) {
        return 1;
    }

    const char* msg = "GetTickCount 返回值是:(见下一行数字)\n";
    DWORD written;
    WriteConsoleA(screen, msg, strlen(msg), &written, NULL);

    const char* note = "(这是个 32 位整数,单位毫秒)\n";
    WriteConsoleA(screen, note, strlen(note), &written, NULL);

    return 0;
}

运行后,它会告诉你 ticks 是一个 32 位数字,表示开机时间。

用 GetTickCount64 

#define _WIN32_WINNT 0x0600 // 支持 Vista 及以上
#include <windows.h>

int main() {
    // 获取当前毫秒数
    ULONGLONG ticks = GetTickCount64();

    // 输出
    HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
    if (screen == INVALID_HANDLE_VALUE) {
        return 1;
    }

    const char* msg = "GetTickCount64 返回值是:(见下一行提示)\n";
    DWORD written;
    WriteConsoleA(screen, msg, strlen(msg), &written, NULL);

    const char* note = "(这是个 64 位整数,单位毫秒)\n";
    WriteConsoleA(screen, note, strlen(note), &written, NULL);

    return 0;
}
  • 运行后,提示 ticks 是一个 64 位数字。

  • 需要加 #define _WIN32_WINNT 0x0600,不然老编译器可能不认识 GetTickCount64。

用法

GetTickCount 最常见的是计时:

  • 测量时间差:比如计算一段代码跑了多久。

  • 控制速度:比如让游戏每秒更新固定的次数。

  • 简单计时器:做一个倒计时或等待效果。

测量时间差的例子

我们测一下等待 2 秒花了多少时间:

#include <windows.h>

int main() {
    HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
    if (screen == INVALID_HANDLE_VALUE) {
        return 1;
    }

    // 开始时间
    DWORD start = GetTickCount();

    // 暂停 2 秒
    Sleep(2000); // 暂停 2000 毫秒

    // 结束时间
    DWORD end = GetTickCount();

    // 时间差
    DWORD difference = end - start;

    // 输出
    const char* msg = "暂停了大约 2000 毫秒,实际差值在下一行\n";
    DWORD written;
    WriteConsoleA(screen, msg, strlen(msg), &written, NULL);

    const char* note = "(差值是个 32 位整数,接近 2000)\n";
    WriteConsoleA(screen, note, strlen(note), &written, NULL);

    return 0;
}

运行结果:

  • Sleep(2000) 暂停 2000 毫秒(2 秒)。

  • difference 差不多是 2000(可能多几毫秒,因为系统调度有误差)。

  • 屏幕显示:“等待时间是 2000 毫秒”。

它们有什么区别?

特性

GetTickCount

GetTickCount64

返回值类型

DWORD

(32 位)

ULONGLONG

(64 位)

最大值

4,294,967,295 毫秒(约 49.7 天)

18,446,744,073,709,551,615 毫秒(约 584,942 年)

溢出

49.7 天后归零

几乎不可能溢出

支持系统

所有 Windows

Windows Vista 及以上

精度

10-16 毫秒误差

10-16 毫秒误差

  • GetTickCount:老版本,适合短期计时,但开机超过 49.7 天会溢出。

  • GetTickCount64:新版本,推荐使用,除非你需要支持 XP。

 

跟其他计时方式对比

  • std::chrono(C++11):

    • 更现代、精确,但需要 C++11 支持。

    • 比如 std::chrono::steady_clock。

  • GetTickCount:

    • 简单粗暴,不需要额外头文件。

    • 但精度不高(通常 10-16 毫秒误差)。

如果是简单计时,GetTickCount 够用了;如果要超高精度,可以用 GetTickCount64 或 QueryPerformanceCounter。

注意事项

  1. 范围限制:

    • DWORD 是 32 位无符号整数,最大值是 4,294,967,295 毫秒(约 49.7 天)。

    • 如果系统运行超过 49.7 天,GetTickCount 会溢出,从 0 开始重新计数。

    • 解决办法:用 GetTickCount64(返回 64 位整数,不会溢出)。

  2. 精度:

    • 误差在 10-16 毫秒,不适合超精确计时。

  3. 时间差计算:

    • 如果溢出发生在 start 和 end 之间,end - start 会出错。要小心处理。

处理溢出的例子

DWORD difference;
if (end >= start) {
    difference = end - start;
} else {
    difference = (0xFFFFFFFF - start) + end + 1; // 处理溢出
}

更有趣的例子

我们做一个闪烁文字的效果:

#include <windows.h>
#include <cstring>

int main() {
    HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
    if (screen == INVALID_HANDLE_VALUE) {
        return 1;
    }

    const char* message = "闪烁!";
    DWORD written;

    for (int i = 0; i < 5; i++) {
        // 显示红字
        SetConsoleTextAttribute(screen, FOREGROUND_RED);
        WriteConsoleA(screen, message, strlen(message), &written, NULL);

        // 等待 500 毫秒
        DWORD start = GetTickCount();
        while (GetTickCount() - start < 500) {}

        // 清屏
        system("cls");

        // 等待 500 毫秒
        start = GetTickCount();
        while (GetTickCount() - start < 500) {}
    }

    return 0;
}

运行结果:

  • “闪烁!” 在屏幕上红字显示 0.5 秒,然后消失 0.5 秒,循环 5 次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值