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

函数原型
要使用 GetTickCount,你需要包含 <windows.h> 头文件。
#include <windows.h> DWORD GetTickCount(void);
参数:
- 该函数不接受任何参数。
返回值:
- 返回一个
DWORD类型的值,表示从系统启动到现在的毫秒数。 DWORD是一个 32 位无符号整数(typedef unsigned long DWORD;)。
主要特点和局限性
特点:
- 简单易用:调用非常简单,无需任何初始化。
- 高精度:以毫秒为单位,对于大多数计时需求(如测量代码执行时间、动画帧率控制等)精度已经足够。
局限性(非常重要!):
-
32 位回绕问题:
DWORD是 32 位无符号整数,它的最大值是2^32 - 1,即4,294,967,295,以毫秒为单位,这个值大约是 7 天。
(图片来源网络,侵删)- 这意味着,如果你的计算机连续运行超过 49.7 天不重启,
GetTickCount的值会从0重新开始计数,如果你在它接近最大值时进行计时,可能会导致计算出的时间差为负数或一个巨大的错误值。 t1 = 4,294,967,294,过了一段时间后t2 = 5。t2 - t1会得到-4,294,967,289,这显然是错误的。
- 这意味着,如果你的计算机连续运行超过 49.7 天不重启,
-
系统时间影响:如果系统时间被用户手动修改(从当前时间调快或调慢),
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类型的变量(lu是unsigned long的格式说明符,在 Windows 上DWORD通常就是unsigned long)。
GetTickCount64 - 解决回绕问题的现代方案
由于 32 位回绕是一个严重的问题,微软从 Windows Vista 和 Windows Server 2008 开始,引入了一个新的函数 GetTickCount64。

#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 的函数。 |
总结与建议
-
如果你正在编写一个新的 Windows 应用程序,并且你的目标平台是 Windows Vista 或更高版本,强烈推荐使用
GetTickCount64,它完美地解决了GetTickCount的回绕问题,使用方式完全相同,是更安全、更现代的选择。 -
如果你需要兼容非常古老的 Windows 系统(如 Windows XP 或更早),并且确定你的程序运行时间不会超过 49.7 天,那么可以使用
GetTickCount。 -
如果你需要比毫秒更高的精度(例如微秒级),那么应该使用
QueryPerformanceCounter。 -
如果你的代码需要跨平台(例如在 Linux 或 macOS 上也能编译运行),那么应该使用 C 标准库的
<time.h>中的clock()函数。
