::::::::::::::::::::::::::::::::::::::::::::::
//本範例轉載至cplusplus.com
#include <stdio.h>
#include <time.h>
void wait( int seconds )
{
clock_t endwait;
endwait = clock () + seconds * CLK_TCK ;
while (clock() < endwait) {}
}
int main ()
{
int n;
printf ("Starting countdown...\n");
for (n=10; n>0; n--)
{
printf ("%d\n",n);
wait (1);
}
printf ("FIRE!!!\n");
return 0;
}
::::::::::::::::::::::::::::::::::::::::::::::
(1)clock_t:在實作時間函數時所定義出的資料型態,但其實是long int,可在time.h裡找到:
#ifndef _CLOCK_T_DEFINED
typedef long clock_t;
#define _CLOCK_T_DEFINED
#endif
(2)CLK_TCK:定義一秒中有幾個clock ticks,在time.h中可以找尋到它的定義:
/* Clock ticks macro - ANSI version */
#define CLOCKS_PER_SEC 1000
/* Non-ANSI names for compatibility */
#define CLK_TCK CLOCKS_PER_SEC
(3)clock():傳回程式啟動後所經過的時間,以滴答(Tick)數目來表示。
(4)此程式在這二行
endwait = clock () + seconds * CLK_TCK ;
while (clock() < endwait) {}
(4會產生些許的誤差,因為當程式處理endwait = clock () + seconds * CLK_TCK ;時,會經過
(4)很短的時間,這時間內所經過的clock數目,但可能不會真得讓你感覺到有誤差。
CLK_TCK是在標題檔所定義的,指每秒中的"滴答"(Tick)數目,那能不能自己從clock()中計算出
CLK_TCK的數值呢?可以的不過是近似值:
::::::::::::::::::::::::::::::::::::::::::::::
#include <stdio.h>
#include <time.h>
void wait( int seconds )
{
clock_t endwait;
endwait = clock () + seconds * CLK_TCK ;
while (clock() < endwait) {}
}
void main()
{
clock_t start_clock,end_clock;
start_clock = clock();
wait(100);
end_clock = clock();
printf("%.2f\n",(end_clock-start_clock)/100.0);
}
:::::::::::::::::::::::::::::::::::::::::::::
取100秒內經過的clock數,除於100,得到1秒內"滴答"的數目你可以取直接取1秒,
則直接得到1秒內"滴答"的數目,但測試的數量少,相對的誤差就大,而測試的數量大
,相對的誤差就小,若不清楚的話,你可以將wait(100)改為wait(1)或wait(1000)
並且同時要將printf(...,../100.0)改為printf(...,../1.0)或printf(...,../1000.0),
你就會曉得為什麼,而不管數量多少,所得的結果近似1000,這就是為什麼time.h內會定義:
#define CLOCKS_PER_SEC 1000
注意以上的程式測試工具是VC6.0,若你使用其它的編譯器的話,可能不會得到相同的結果
,比如在Turbo C++中,CLK_TCK的定義是:
#define CLK_TCK 18.2
#define CLOCKS_PER_SEC 18.2
而將範例2的程式在Turbo C++測試大約是19.00,可以試試看。
Turbo C/C++是16位元的編譯器,操作在real mode底上,可以使用interrupt(中斷)來取得硬體的資訊(時間、日期...)
,在Turbo C/C++中,時間函數是利用中斷的方式來產生的,所依據的是PC上的計時IC8253/8254(I/O PORT 40h,
41h,42h,43h),計時計數器每55毫秒(ms)約1/18.2秒產生一個插斷,插斷便會把計算值加一。有關這方面的內容可
以參考有關微處理機或BIOS相關的書籍。所以55毫秒算是最小最基本的時間單位,數值比它還小的話,無法在real mode
下表達出來,所以55ms稱為解析度(resolution),所能表示時間刻度的最小單位。若以若你要撰寫一個計時器,而時間
能小到1毫秒的話,你就無法使用clock()來撰寫。
在VC6.0中,會隨著系統的不同而解析度有所不同,因為作者之前在WIN98測試的結果,clock()的增量大約50
(理論值55 [1000/18.2 =55ms]),而CLK_TCK是1000,相除約為55毫秒,解析度是與Turbo C/C++一樣的。
但在目前的作業系統WIN2K上,測出的結果,clock()的增量是10,解析度是10毫秒,這與PC上的計時IC不一樣
,因為WIN2K是在Protect mode底下,使用插斷的方式會產生exception,所以VC產生的時間函數不是利用中斷
的方式來產生。時間函數是利用系統所提供的資訊及函數所組成的。要怎麼取得系統的解析度呢?可以試試
函數GetSystemTimerAdjuestment來取得。
Written By James On 2004/02/08