C语言中提供了许多库函数来实现计时功能
下面介绍一些常用的计时函数
1. time()
头文件:time.h
函数原型:time_t time(time_t * timer)
功能:返回以格林尼治时间(GMT)为标准,从1970年1月1日00:00:00到现在的时此刻所经过的秒数
用time()函数结合其他函数(如:localtime、gmtime、asctime、ctime)可以获得当前系统时间或是标准时间。
用difftime函数可以计算两个time_t类型的时间的差值,可以用于计时。用difftime(t2,t1)要比t2-t1更准确,因为C标准中并没有规定time_t的单位一定是秒,而difftime会根据机器进行转换,更可靠。
说明:C标准库中的函数,可移植性最好,性能也很稳定,但精度太低,只能精确到秒,对于一般的事件计时还算够用,而对运算时间的计时就明显不够用了。
2. clock()
头文件:time.h
函数原型:clock_t clock(void)
功能:该函数返回值是硬件滴答数,要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC。比如,在VC++6.0下,这两个量的值都是1000。
说明:可以精确到毫秒,适合一般场合的使用。
3. timeGetTime()
头文件:Mmsystem.h 引用库: Winmm.lib
函数原型:DWORD timeGetTime(VOID)
功能:返回系统时间,以毫秒为单位。系统时间是从系统启动到调用函数时所经过的毫秒数。注意,这个值是32位的,会在0到2^32之间循环,约49.71天。
说明:该函数的时间精度是五毫秒或更大一些,这取决于机器的性能。可用timeBeginPeriod和timeEndPeriod函数提高timeGetTime函数的精度。如果使用了,连续调用timeGetTime函数,一系列返回值的差异由timeBeginPeriod和timeEndPeriod决定。
4. GetTickCount()
头文件:windows.h
函数原型:DWORD WINAPI GetTickCount(void)
功能:返回自设备启动后的毫秒数(不含系统暂停时间)。
说明:精确到毫秒。对于一般的实时控制,使用GetTickCount()函数就可以满足精度要求。
5. QueryPerformanceCounter()、QueryPerformanceFrequency()
头文件:windows.h
函数原型:BOOLQueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)
BOOLQueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)
功能:前者获得的是CPU从开机以来执行的时钟周期数。后者用于获得你的机器一秒钟执行多少次,就是你的时钟周期。
补充:LARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构, 其具体用法根据编译器是否支持64位而定:
在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率,然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经历的精确时间。
说明:这种方法的定时误差不超过1微秒,精度与CPU等机器配置有关,一般认为精度为透微秒级。在Windows平台下进行高精度计时的时候可以考虑这种方法。
6. gettimeofday()
Linux C函数。
头文件:sys/time.h
函数原型:int gettimeofday(struct timeval *tv,struct timezone *tz)
说明:其参数tv是保存获取时间结果的结构体,参数tz用于保存时区结果(若不使用则传入NULL即可)。
timeval的定义为:
struct timeval {
long tv_sec // 秒数
long tv_usec //微秒数
}
可见该函数可用于在linux中获得微秒精度的时间。
说明:使用这种方式计时,精度可达微秒。经验证,在arm+linux的环境下此函数仍可使用。
秒表计时器的代码#include
#include
#include
#include
struct
tm
//定义时间结构体,包括时分秒和10毫秒
{
int
hours,minutes,seconds
int
hscd
}time,tmp,total
//time用以计时显示,tmp用以存储上一阶段时间,total记总时间
int
cnt
file*
fout
//每次调用update函数,相当于时间过了10ms
void
update(struct
tm
*t)
{
(*t).hscd++
//10ms单位时间加1
cnt++
if
((*t).hscd==100)
//计时满1s,进位
{
(*t).hscd=0
(*t).seconds++
}
if
((*t).seconds==60)
//计时满一分,进位
{
(*t).seconds=0
(*t).minutes++
}
if
((*t).minutes==60)
//计时满一小时,进位
{
(*t).minutes=0
(*t).hours++
}
if((*t).hours==24)
(*t).hours=0
//delay()
sleep(10)
//sleep是windows提供的函数,作用是暂停程序,单位毫秒,所以此处暂停10ms
}
void
display(struct
tm
*t)
{
//此处输出计时结果,\r为回车不换行,既一直在同一行更新时间
printf("%d:",(*t).hours)
printf("%d:",(*t).minutes)
printf("%d:",(*t).seconds)
printf("%d\r",(*t).hscd)
//printf("now,
press
‘e’
key
to
stop
the
clock…")
}
void
time_init()
//初始化时间
{
time.hours=time.minutes=time.seconds=time.hscd=0
}
void
get_total()
//计算总时间
{
total.hscd
=
cnt
%
100
cnt
/=
100
total.seconds
=
cnt
%
60
cnt
/=
60
total.minutes
=
cnt
%
60
cnt
/=
60
total.hours
=
cnt
}
int
main()
{
char
m
time_init()
cnt
=
0
fout
=
fopen("timeout.txt","w")
printf("按回车键开始计时!\n")
while(1)
{
m
=
getch()
if(m
!=
‘\r’)
//读入一个输入,如果是回车,那么跳出次循环
printf("输入错误,仅能输入回车键!\n")
else
break
}
printf("已经开始计时,但是你可以按回车键以分段计时!\n")
while(1)
{
if(kbhit())
//此处检查是否有键盘输入
{
m=getch()
if(m
==
‘\r’)
//如果等于回车,那么计时结束,跳出循环
break
else
if(m
==
‘
‘)
//如果等于空格,显示此次计时,初始化计时器
{
tmp
=
time
//记录上一段计时器结果
fprintf(fout,"%d:%d:%d:%d\n",tmp.hours,tmp.minutes,tmp.seconds,tmp.hscd)
//写入文件
time_init()
printf("\n")
}
else
{
printf("输入错误,仅支持输入回车键或者空格键!\n")
}
}
update(&time)
//更新计时器
display(&time)
//显示计时器时间
}
tmp
=
time
//输出最后一次即使结果,写入文件
fprintf(fout,"%d:%d:%d:%d\n",tmp.hours,tmp.minutes,tmp.seconds,tmp.hscd)
get_total()
//计算总的时间,显示,并写入文件
printf("\n总时间:%d:%d:%d:%d\n",total.hours,total.minutes,total.seconds,total.hscd)
fprintf(fout,"统计时间:%d:%d:%d:%d\n",total.hours,total.minutes,total.seconds,total.hscd)
fclose(fout)
printf("已经保存到当前目录下的timeout.txt文件中按任意键结束!")
getch()
}