C語言計時函式
time()函式與time_t型別
標頭檔案:time.h
函式簽名:time_t time( time_t *arg )
說明:返回當前計算機紀元時間,並將其儲存在arg指向的time_t型別中。所以可以time_t result = time(NULL)
,也可以time(&result)
。
計算機紀元時間:C語言和Unix創造並誕生於1970年,所以計算機以1970年1月1日作為紀元開始時間。
C語言標準並沒有指定time_t型別的編碼方式,但大多數遵循POSIX標準系統的time_t一般是32位有符號整數實現,以秒為最小單位,從1970年1月1日開始計數,所以能表示到2038年。
VS2017中有如下定義:
#ifndef _CRT_NO_TIME_T
#ifdef _USE_32BIT_TIME_T
typedef __time32_t time_t;
#else
typedef __time64_t time_t;
#endif
#endif
...
#ifdef _USE_32BIT_TIME_T
...
static __inline time_t __CRTDECL time(
_Out_opt_ time_t* const _Time
)
{
return _time32(_Time);
}
...
#else
...
static __inline time_t __CRTDECL time(
_Out_opt_ time_t* const _Time
)
{
return _time64(_Time);
}
...
#endif
因為time_t型別編碼不能確定,所以儘量不要用t1-t2
方式計算兩個time_t
之間的時間間隔,而應該用double difftime( time_t time_end, time_t time_beg );
擴充套件:time_t
表示計算機紀元時間,struct tm
表示標準日曆時間。
struct tm
定義如下:
struct tm
{
int tm_sec; // seconds after the minute - [0, 60] including leap second
int tm_min; // minutes after the hour - [0, 59]
int tm_hour; // hours since midnight - [0, 23]
int tm_mday; // day of the month - [1, 31]
int tm_mon; // months since January - [0, 11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday - [0, 6]
int tm_yday; // days since January 1 - [0, 365]
int tm_isdst; // daylight savings time flag
};
time_t
可以和struct tm
格式的時間進行互相轉換:
struct tm *gmtime( const time_t *time )
:從time_t
轉成struct tm
,但該函式C11標準中才定義的。time_t mktime( struct tm *time )
:從struct tm
轉成time_t
。
示例:
time_t start, end;
start = time(NULL);
_sleep(1000);
end = time(NULL);
printf("start time: %s\n", ctime(&start));
printf("end time: %s\n", ctime(&end));
printf("duration: %lf\n", difftime(end, start));
執行結果:
start time: Fri Jul 28 09:48:25 2017
end time: Fri Jul 28 09:48:26 2017
duration: 1.000000
總結:C標準庫中的函式,可移植性最好,效能也很穩定,但精度太低,只能精確到秒,對於一般的事件計時還算夠用,而對運算時間的計時就明顯不夠用了。
clock()函式與clock_t型別
標頭檔案:time.h
函式簽名:clock_t clock(void)
說明:該函式返回值是硬體滴答數(未加工的程式啟動時開始經過的處理器時間),只有計算呼叫兩次clock的返回值才有意義,要換算成秒,需要除以CLOCKS_PER_SEC(每秒中的滴答數),VC中定義如下:
#define CLOCKS_PER_SEC ((clock_t)1000)
當CPU被多個程序共享,clock返回值可能慢於真實時鐘,而如果一個程序內有多個執行緒或者多核處理,clock返回值可能快於真實時鐘。
注意:在32位機器上clock_t為32bit,所以clock_t在2147483648
(2147秒或36分)後會回滾(即小於零)。
示例:
示例1
clock_t start, end;
start = clock();
_sleep(1234);
end = clock();
double duration = ((double)end - start) / CLOCKS_PER_SEC;
printf("%f second", duration);
執行結果:
1.234000 second
示例二:
clock_t start, end;
start = clock();
_sleep(1234);
end = clock();
int duration = end - start;
printf("%d millisecond", duration);
執行結果:
1234 millisecond
總結:可以精確到毫秒,適合一般場合的使用。
timespec_get()函式與timespec型別
標頭檔案:time.h
函式簽名:int timespec_get( struct timespec *ts, int base)
(since C11)
說明:以base為基底,將當前計算機紀元時間填充到ts地址中。
timespec結構體定義如下:
struct timespec
{
time_t tv_sec; // Seconds - >= 0
long tv_nsec; // Nanoseconds - [0, 999999999]
};
timespec精度是納秒級。
C11標準中定義TIME_UTC
為通用協調時間,並推薦使用TIME_UTC作為base基底。
示例:
struct timespec start, end;
timespec_get(&start, TIME_UTC);
_sleep(1234);
timespec_get(&end, TIME_UTC);
char buffer[128];
strftime(buffer, sizeof(buffer), "%Y/%m/%d %T", gmtime(&start.tv_sec));
printf("start time: %s.%ld\n", buffer, start.tv_nsec);
strftime(buffer, sizeof(buffer), "%Y/%m/%d %T", gmtime(&end.tv_sec));
printf("end time: %s.%ld\n", buffer, end.tv_nsec);
time_t d_sec = end.tv_sec - start.tv_sec;
long d_nsec = end.tv_nsec - start.tv_nsec;
long duration = d_sec*1E9 + d_nsec;
printf("duration: %ld nanosecond\n", duration);
執行結果:
start time: 2017/07/28 04:34:26.577550200
end time: 2017/07/28 04:34:27.811685800
duration: 1234135600 nanosecond
總結:C11標準庫函式,跨平臺特性好,精度能達到納秒級,但是需要編譯器支援C11。
以上是C語言標準庫提供的函式,跨平臺特性較好,下面的幾個是特定平臺的API,所以視情況使用。
timeGetTime()函式
標頭檔案:timeapi.h(Windows.h中已經包括該標頭檔案)
函式簽名:DWORD timeGetTime(void)
庫:Winmm.lib;Dll:Winmm.dll
說明:返回系統時間,以毫秒為單位。
timeGetTime函式返回值是一個DWORD(32bit),會在0到
timeGetTime函式的預設精度可以達到5毫秒或者更多,這個精度依賴於機器。可以使用timeBeginPeriod和timeEndPeriod函式增加timeGetTime的精度。timeGetTime返回的兩個連續值之間的最小間隔可以和timeBeginPeriod和timeEndPeriod設定的最小週期一樣大。
timeGetTime以DWORD儲存時間
timeGetSystemTime以MMTIME結構體儲存時間
示例:
示例一:
#include<Windows.h>
#pragma comment(lib,"Winmm.lib")
int main() {
DWORD start, end;
start = timeGetTime();
Sleep(1234);
end = timeGetTime();
printf("%d\n", end - start);
}
執行結果:
1235
示例二:
#include<Windows.h>
#pragma comment(lib,"Winmm.lib")
int main() {
DWORD start, end;
timeBeginPeriod(1);
start = timeGetTime();
Sleep(1234);
end = timeGetTime();
timeEndPeriod(1);
printf("%d\n", end - start);
}
執行結果:
1234
GetTickCount函式
標頭檔案:Winbase.h(Windows.h中已經包括該標頭檔案)
函式簽名:DWORD WINAPI GetTickCount(void);
庫:Kernel32.lib;Dll:Kernel32.dll
說明:返回系統啟動後的時間,單位為毫秒。
GetTickCount功能只限於系統定時器,精度在10毫秒到16毫秒之間。GetTickCount的精度不受GetSystemTimeAdjustment函式影響。
該函式以DWORD(32bit)儲存時間,如果系統連續執行49.7天,將會迴圈到0,為避免這個影響,建議使用GetTickCount64函式
示例:
#include<Windows.h>
int main() {
DWORD start, end;
start = GetTickCount();
Sleep(1234);
end = GetTickCount();
printf("%d\n", end - start);
}
執行結果:
1234
QueryPerformanceCounter()、QueryPerformanceFrequency()高精度時間
標頭檔案:Winbase.h (Windows.h中已經包括該標頭檔案)
函式簽名:
BOOL WINAPI QueryPerformanceCounter( _Out_ LARGE_INTEGER *lpPerformanceCount );
BOOL WINAPI QueryPerformanceFrequency( _Out_ LARGE_INTEGER *lpFrequency );
庫:Kernel32.lib;Dll:Kernel32.dll
說明:QueryPerformanceFrequency獲取CPU時鐘頻率;QueryPerformanceCounter獲取CPU時鐘計數器的當前值。通過這兩個函式可以計算兩點之間的時間間隔,精度為微妙級別。
LARGE_INTEGER定義如下:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
} DUMMYSTRUCTNAME;
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
示例:
#include<Windows.h>
DWORD64 ObtainCurrentTime() {
LARGE_INTEGER num;
QueryPerformanceCounter(&num);
return num.QuadPart;
}
DOUBLE ComputeDuration(DWORD64 end, DWORD64 start) {
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return (DOUBLE)(end - start) / frequency.QuadPart;
}
int main() {
DWORD64 start, end;
start = ObtainCurrentTime();
Sleep(1234);
end = ObtainCurrentTime();
DOUBLE duration = ComputeDuration(end, start);
printf("%lf microsecond", duration);
}
執行結果:
1.234634 microsecond
相關推薦
C語言計時函式
time()函式與time_t型別 標頭檔案:time.h 函式簽名:time_t time( time_t *arg ) 說明:返回當前計算機紀元時間,並將其儲存在arg指向的time_t型別中。所以可以time_t result = time(NULL
C語言計時函式clock()
C語言clock()函式實現計時功能 函式clock()返回值為clock_t型別(一個長整型數),它的實際意義是指“程序啟動到呼叫clock()函式經過了多少個CPU時鐘計時單元”,藉助
C語言 trim函式實現
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> //去除尾部空格 char *rtrim(char *str) { if(str == N
C語言中函式宣告、形參、實參
函式原型: 原型prototype是函式的宣告;描述了函式的返回值與引數; 函式原型說明了兩點: 1、該函式的返回值 2、該函式的引數及其型別 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 函式的引數: 引數到底是什
C語言isalpha函式
看程式碼: #include<ctype.h> #include<stdio.h> #include <iostream> using namespace std; int main(void){ char ch; int tot
c 語言 用函式遞迴來實現求 k 的 n 次方
如果求取k的n次方,既可以用普通的方法實現,也可以用函式的遞迴來實現。 函式的遞迴即是自己呼叫自己的函式應用形式,即在main函式下定義一個函式,然後在這個函式內自己為了實現某個目的,函式
用C語言探究函式遞迴的巧妙之處(以斐波那契數列為例)
對於許多C語言的初學者來說,函式是一個比較重要的版塊.函式的使用不僅在學習程式設計的時期可以方便我們解決一些問題.它在未來的工作中也是程式設計師們經常運用的東西.而函式的遞迴是函式這一版塊比較難懂的東西.因此小編以輸出斐波那契數列的第N項為例,來探討函式的遞迴的應用給我們的程式碼帶來的方便.
C語言 strrev函式
標頭檔案:#include<string.h> strrev()函式將字串逆置,其原型為: char *strrev(char *str); 【引數說明】str為要逆置的字串。 strrev()將str所指的字串逆置。 【返回值】返回指向逆置後的字串的指標。 strr
C語言庫函式(侵刪)
1.strlen 標頭檔案:#include <string.h> strlen()函式用來計算字串的長度,其原型為:unsigned int strlen (char *s); s為指定的字串 #include<stdio.h> #include<
C語言assert函式完全攻略
斷言assert函式,C語言assert函式完全攻略 對於斷言,相信大家都不陌生,大多數程式語言也都有斷言這一特性。簡單地講,斷言就是對某種假設條件進行檢查。在 C 語言中,斷言被定義為巨集的形式(assert(expression)),而不是函式,其原型定義在<assert.h>檔
C語言read函式的那些坑
今天在複習UNIX檔案系統,用到那個read函式,但是無意中卻掉到一個坑裡了,用了一個多小時才找到問題根源,這裡記錄一下。 問題是這樣的:我需要使用read和write函式把鍵盤輸入的資訊複製到輸出。所以我寫了如下程式: #include<stdio.h> #define MAX
linux下的c語言系統函式呼叫
目錄 4.linux下的系統函式的使用 c語言 4.1數學函式的使用 1pow函式 2.exp函式 3.log函式 4.rand()隨機數函式 4.2字元函式的使用 4.3系統時間與日期函式的使用 系統時間 時間間隔 4.4環境控制函式 &nb
Mr.J--C語言頭函式的建立(附嚴薇敏《資料結構》線性表程式碼)
如何正確編寫 C 語言標頭檔案和與之相關聯的 c 源程式檔案 檢視此文章需要有一定的C語言程式設計基礎 首先就要了解它們的各自功能。要理解C 檔案與標頭檔案(即.h)有什麼 不同之處,首先需要弄明白編譯器的工作過程。 一般說來編譯器會做以下幾個過程: 1.預處理階段 2
C語言隨機函式的使用
rand()和srand()應該是初學者最先接觸到的隨機函數了,今天博主就這兩個函式陳述一下自己的理解。 這兩個函式的使用規範如下: /*這是一個模擬擲色子1800次的程式*/ #include <stdlib.h>
C語言中函式指標陣列的初始化和使用
不比多說上一個程式碼,就懂了! 程式碼一: #include <stdio.h> int func(int i) { printf("%d\n",i); return i*i; } int
C語言malloc()函式與calloc()函式的區別
推薦部落格: 推薦部落格:https://blog.csdn.net/ddcodingya/article/details/80452397 推薦部落格:https:https://blog.csdn.net/Hackbuteer1/article/d
C語言 socket函式的簡單運用 29
下面所講的是在Linux系統上用gcc編寫的,Windows好像不能用。 socket是套接字,是用來在網路之間進行資料傳遞的。 在網路中,我們通過一個IP來確定一臺主機,再通過一個port來確定一個進行,而socket就是一個進行。因此:socket = IP + port 網路傳輸的
Linux : C語言pause()函式:讓程序暫停直到訊號出現
C語言pause()函式:讓程序暫停直到訊號出現 相關函式:kill, signal, sleep 標頭檔案:#include <unistd.h> 定義函式:int
c語言輸入函式getchar&fgets&scanf&scanf_s
//a)getchar:在鍵盤上輸入一個ASCII碼的文字,返回值得到的是一個數值, //c=getchar等價於scanf("%c",&c);在第一次執行時時阻塞,並等待輸入。 //如果下一次輸入緩衝中有剩餘還未提取的輸入資料,將不阻塞直接提取那些剩餘的資料; //b)fflush(std
C語言:函式中引數的傳值與傳地址
任務程式碼: #include <stdio.h> void swap(int *a ,int *b)//按之前對指標認識,*a代表指標變數a,a儲存的是地址,*a是地址的值。 { //但是可以看到下面傳輸過程中swap(