c语言 gettickcount

99ANYc3cd6
预计阅读时长 13 分钟
位置: 首页 C语言 正文

GetTickCount 是一个在 Windows 平台上非常常用的 Windows API (Application Programming Interface) 函数,它的主要作用是获取自 Windows 操作系统启动以来所经过的 毫秒数,它不是标准 C 语言库的一部分,而是特定于 Windows 系统的。

c语言 gettickcount
(图片来源网络,侵删)

函数原型

要使用 GetTickCount,你需要包含 <windows.h> 头文件。

#include <windows.h>
DWORD GetTickCount(void);

参数:

  • 该函数不接受任何参数。

返回值:

  • 返回一个 DWORD 类型的值,表示从系统启动到现在的毫秒数。
  • DWORD 是一个 32 位无符号整数(typedef unsigned long DWORD;)。

主要特点和局限性

特点:

  1. 简单易用:调用非常简单,无需任何初始化。
  2. 高精度:以毫秒为单位,对于大多数计时需求(如测量代码执行时间、动画帧率控制等)精度已经足够。

局限性(非常重要!):

  1. 32 位回绕问题DWORD 是 32 位无符号整数,它的最大值是 2^32 - 1,即 4,294,967,295,以毫秒为单位,这个值大约是 7 天

    c语言 gettickcount
    (图片来源网络,侵删)
    • 这意味着,如果你的计算机连续运行超过 49.7 天不重启,GetTickCount 的值会从 0 重新开始计数,如果你在它接近最大值时进行计时,可能会导致计算出的时间差为负数或一个巨大的错误值。
    • t1 = 4,294,967,294,过了一段时间后 t2 = 5t2 - t1 会得到 -4,294,967,289,这显然是错误的。
  2. 系统时间影响:如果系统时间被用户手动修改(从当前时间调快或调慢),GetTickCount 的值 不会 因此改变,它只记录物理上的流逝时间,这是它的一个优点,也是一个缺点(取决于你的需求)。


如何正确使用 GetTickCount

最常见的用途是测量一段代码的执行时间。

#include <stdio.h>
#include <windows.h> // 必须包含此头文件
int main() {
    // 1. 获取开始时间点
    DWORD startTime = GetTickCount();
    // 2. 执行你想要计时的代码
    // 这里用一个简单的循环来模拟耗时操作
    volatile int sum = 0;
    for (int i = 0; i < 100000000; ++i) {
        sum += i;
    }
    printf("Sum: %d\n", sum); // volatile 防止编译器优化掉循环
    // 3. 获取结束时间点
    DWORD endTime = GetTickCount();
    // 4. 计算耗时(毫秒)
    DWORD elapsedTime = endTime - startTime;
    // 5. 输出结果
    printf("代码执行耗时: %lu 毫秒\n", elapsedTime);
    printf("代码执行耗时: %.3f 秒\n", (double)elapsedTime / 1000.0);
    return 0;
}

代码解释:

  • #include <windows.h>: 包含了 GetTickCount 函数的声明。
  • DWORD startTime = GetTickCount(): 在代码块执行前记录一个时间戳。
  • DWORD endTime = GetTickCount(): 在代码块执行后记录另一个时间戳。
  • DWORD elapsedTime = endTime - startTime: 两者之差就是代码执行消耗的毫秒数。
  • printf: 使用 %lu 来打印 DWORD 类型的变量(luunsigned long 的格式说明符,在 Windows 上 DWORD 通常就是 unsigned long)。

GetTickCount64 - 解决回绕问题的现代方案

由于 32 位回绕是一个严重的问题,微软从 Windows Vista 和 Windows Server 2008 开始,引入了一个新的函数 GetTickCount64

c语言 gettickcount
(图片来源网络,侵删)
#include <windows.h>
ULONGLONG GetTickCount64(void);

GetTickCount 的区别:

  • 返回值类型: ULONGLONG 是一个 64 位无符号整数(typedef unsigned __int64 ULONGLONG;)。
  • 回绕问题: 2^64 毫秒是一个极其巨大的数字(约 5.8 亿年),因此在实际应用中,几乎不可能发生回绕,这是目前推荐使用的计时方法。

示例代码:

#include <stdio.h>
#include <windows.h>
int main() {
    // 使用 GetTickCount64
    ULONGLONG startTime = GetTickCount64();
    // ... 某些耗时操作 ...
    Sleep(1000); // 暂停1秒,用于演示
    ULONGLONG endTime = GetTickCount64();
    ULONGLONG elapsedTime = endTime - startTime;
    printf("使用 GetTickCount64 测量耗时: %llu 毫秒\n", elapsedTime);
    return 0;
}

其他计时方法对比

函数 精度 回绕问题 适用场景
GetTickCount 毫秒 (约49.7天) 简单计时,对精度要求不高,且确定运行时间不会超过回绕周期。
GetTickCount64 毫秒 (约5.8亿年) 现代 Windows 应用推荐,需要高可靠性、长时间运行的计时任务。
QueryPerformanceCounter 非常高 (微秒/纳秒级) 需要极高精度的计时,例如性能分析、游戏物理引擎、基准测试。
clock() (C标准库) 毫秒 可移植性好(跨平台),但精度通常低于 Windows API 的函数。

总结与建议

  1. 如果你正在编写一个新的 Windows 应用程序,并且你的目标平台是 Windows Vista 或更高版本,强烈推荐使用 GetTickCount64,它完美地解决了 GetTickCount 的回绕问题,使用方式完全相同,是更安全、更现代的选择。

  2. 如果你需要兼容非常古老的 Windows 系统(如 Windows XP 或更早),并且确定你的程序运行时间不会超过 49.7 天,那么可以使用 GetTickCount

  3. 如果你需要比毫秒更高的精度(例如微秒级),那么应该使用 QueryPerformanceCounter

  4. 如果你的代码需要跨平台(例如在 Linux 或 macOS 上也能编译运行),那么应该使用 C 标准库的 <time.h> 中的 clock() 函数。

-- 展开阅读全文 --
头像
Linux C中sleep函数精确休眠实现原理?
« 上一篇 2025-12-22
织梦 更新主页html 空白
下一篇 » 2025-12-22

相关文章

取消
微信二维码
支付宝二维码

目录[+]