C++如何實(shí)現(xiàn)簡(jiǎn)單的計(jì)時(shí)器詳解
實(shí)現(xiàn)分析
首先我們先分析一下計(jì)時(shí)器的一些功能,簡(jiǎn)單一點(diǎn)的計(jì)時(shí)器包括開(kāi)始、暫停、停止和顯示基本功能,這些功能以C++面向?qū)ο蟮木幊趟枷耄∣OP)進(jìn)行抽象,就是計(jì)時(shí)器類(lèi)(Timer)的4個(gè)成員函數(shù),當(dāng)然我們要把這些函數(shù)作為公有的,因?yàn)樗鼈兪橇艚o外部的接口(interface)。
然后我們?cè)俜治鲆幌掠?jì)時(shí)器的三種狀態(tài):停止,正在運(yùn)行,暫停(注意:暫停不是停止),那么怎么記錄計(jì)時(shí)器的三種狀態(tài)呢?
這里我們用布爾類(lèi)型的變量記錄計(jì)時(shí)器的三種狀態(tài),分別為bool is_pause,bool is_stop,在這里一定要注意變量的命名,就像這樣見(jiàn)名知意。吐舌頭當(dāng)然為了體現(xiàn)C++類(lèi)的封裝性,要把這兩個(gè)bool變量作為計(jì)時(shí)器類(lèi)(Timer)的私有成員。
實(shí)現(xiàn)方法
重要的問(wèn)題來(lái)了,我們?cè)趺磳?shí)現(xiàn)計(jì)時(shí)呢?吶,你們知道time()
函數(shù)嗎?簡(jiǎn)單的說(shuō)一下time函數(shù):這個(gè)函數(shù)在time.h頭文件中,它返回自 Unix 紀(jì)元(January 1 1970 00:00:00 GMT)起的當(dāng)前時(shí)間的秒數(shù),是一個(gè)長(zhǎng)整形(long)。這樣我們?cè)谟?jì)時(shí)器開(kāi)始的時(shí)候獲取一個(gè)time函數(shù)的返回值,保存到一個(gè)變量中,在用一個(gè)變量保存暫停時(shí)的時(shí)間。當(dāng)我們開(kāi)始計(jì)時(shí)的時(shí)候,進(jìn)入一個(gè)死循環(huán),始終用time()
-開(kāi)始的時(shí)間,就是當(dāng)前計(jì)時(shí)器的時(shí)間。(不要急,具體實(shí)現(xiàn)往下看)。此時(shí)為了保存開(kāi)始和暫停時(shí)刻的時(shí)間,必須在計(jì)時(shí)器類(lèi)(Timer)中增加兩個(gè)長(zhǎng)整形(long)變量:start_time,pause_time,當(dāng)然作為私有變量。
好像還少點(diǎn)什么......為了讓外部獲取當(dāng)前計(jì)時(shí)器的狀態(tài),我們還需要兩個(gè)函數(shù)返回計(jì)時(shí)器的狀態(tài),is_pause()
計(jì)時(shí)器是否處于暫停,is_stop()
計(jì)時(shí)器是否處于停止?fàn)顟B(tài),返回值的類(lèi)型為bool。
驚訝別忘了Timer的構(gòu)造函數(shù),用來(lái)做一些初始化的工作!
好了,至此我們的計(jì)時(shí)器類(lèi)設(shè)計(jì)完成了(prefect),代碼在下面:
class Timer { private: long start_time; long pause_time; //兩個(gè)bool值標(biāo)記四種狀態(tài) bool is_pause; //記錄計(jì)時(shí)器的狀態(tài) (是否處于暫停狀態(tài)) bool is_stop;//是否處于停止?fàn)顟B(tài) public: Timer(); bool isPause(); //返回計(jì)時(shí)器狀態(tài) bool isStop(); //計(jì)時(shí)器的三種動(dòng)作(功能) void Start(); void Pause(); void Stop(); inline long getStartTime() {return start_time;} void show(); };
接下來(lái)的任務(wù)就是實(shí)現(xiàn)Timer的成員函數(shù)了..............
首先是構(gòu)造函數(shù)Timer::Timer()
,完成一些初始化的工作:
Timer::Timer() { is_pause = false; //初始化計(jì)時(shí)器狀態(tài) is_stop = true; }
計(jì)時(shí)器開(kāi)始計(jì)時(shí)之前應(yīng)該處于停止?fàn)顟B(tài)?。ㄓ?jì)時(shí)器只能處于一種狀態(tài),不要犯糊涂哦!)
成員函數(shù)isPause()
它的作用僅是讓外部獲取計(jì)時(shí)器是否處于暫停狀態(tài),so easy
bool Timer::isPause() { if(is_pause) return true; else return false; }
isStop函數(shù)和isPause一樣只是一個(gè)接口,讓外部獲取計(jì)時(shí)器的狀態(tài):
bool Timer::isStop()
{
if(is_stop)
return true;
return false;
}
下面是Timer::Start()
函數(shù)的實(shí)現(xiàn),它是計(jì)時(shí)器開(kāi)始的時(shí)候要運(yùn)行的函數(shù):
void Timer::Start() //開(kāi)始 { if(is_stop) { start_time = time(0); is_stop = false; } else if(is_pause) { is_pause = false; start_time += time(0)-pause_time; //更新開(kāi)始時(shí)間:用此時(shí)的時(shí)間 - 暫停時(shí)所用的時(shí)間 + 上一次開(kāi)始的時(shí)間 = 此時(shí)的開(kāi)始時(shí)間 } }
我們首先判斷一下計(jì)時(shí)的狀態(tài),如果處于停止?fàn)顟B(tài),獲取開(kāi)始的時(shí)間,然后更新計(jì)時(shí)器的狀態(tài);如果計(jì)時(shí)器正處在暫停狀態(tài),我們讓計(jì)時(shí)器繼續(xù)計(jì)時(shí),我采用改變開(kāi)始的計(jì)時(shí)的時(shí)間(start_time)去調(diào)整計(jì)時(shí)的時(shí)間 : (用此時(shí)的時(shí)間 - 暫停時(shí)所用的時(shí)間 + 上一次開(kāi)始的時(shí)間 = 此時(shí)的開(kāi)始時(shí)間)。如果計(jì)時(shí)器正處于運(yùn)行狀態(tài),就什么也不做!(不知道大家能不能看的懂.....)
這是暫停函數(shù)Timer::Pause()
的實(shí)現(xiàn):
void Timer::Pause() //暫停 { if(is_stop||is_pause) //如果處于停止/暫停狀態(tài),此動(dòng)作不做任何處理,直接返回 return; else //否則調(diào)制為暫停狀態(tài) { is_pause = true; pause_time = time(0); //獲取暫停時(shí)間 } }
如果沒(méi)有在運(yùn)行,也就是處于暫?;蛲V?fàn)顟B(tài),什么也不做直接返回。否則就去處理暫停請(qǐng)求:既然我們進(jìn)行了暫停的操作,就要改變計(jì)時(shí)器的狀態(tài),將狀態(tài)設(shè)置為暫停,保存此刻的時(shí)間,(這個(gè)暫停的時(shí)間pause_time在上面的開(kāi)始的函數(shù)中用的到!)。
接著我們?nèi)?shí)現(xiàn)停止函數(shù)Timer::Stop():
void Timer::Stop() //停止 { if(is_stop) //如果正處于停止?fàn)顟B(tài)(不是暫停狀態(tài)),不做任何處理 return ; else if(is_pause) //改變計(jì)時(shí)器狀態(tài) { is_pause = false; is_stop = true; } else if(!is_stop) { is_stop = true; } }
如果處于停止?fàn)顟B(tài),直接返回。否則如果處于暫停狀態(tài)改變計(jì)時(shí)器的狀態(tài)為is_stop = true
;否則就是處于運(yùn)行狀態(tài),直接改變計(jì)時(shí)器的狀態(tài)為停止。
下面是顯示時(shí)間的函數(shù)Timer::show()
:
void Timer::show() { long t = time(0) - start_time; gotoxy(35,12); cout<<setw(2)<<setfill('0')<<t/60/60<<":" <<setw(2)<<setfill('0')<<t/60<<":" <<setw(2)<<setfill('0')<<t%60<<endl; }
這里我要說(shuō)一下gotoxy(int x,int y)
函數(shù),它的作用是將控制臺(tái)的光標(biāo)定位到坐標(biāo)(x,y)處,show函數(shù)是要放到死循環(huán)中的,所以這樣始終將輸出的時(shí)間打印到一個(gè)地方,實(shí)現(xiàn)了時(shí)間的更新(我是不是很聰明);setw(int x)
是設(shè)置輸出的字寬,setfill(char ch)
設(shè)置了字符的填充。time函數(shù)返回的是秒數(shù),t/60/60得到小時(shí),t/60得到分鐘,t%60得到秒數(shù)。
下面就是主函數(shù)了main()
int main() { Timer t; char ch; hidden();//隱藏光標(biāo) system("color 02"); gotoxy(35,12); cout<<"00:00:00"; gotoxy(20,18); cout<<"按a開(kāi)始,按空格暫停,按s停止"; while(1) { if(kbhit()) { ch = getch(); switch (ch) { case 'a':t.Start();break; case 's':t.Stop();break; case ' ':t.Pause();break; default :break; } } if(!t.isStop()&&!t.isPause()) { t.show(); } } }
Timer t;定義一個(gè)計(jì)時(shí)器。hidden()
;是用來(lái)隱藏控制臺(tái)光標(biāo)的,不是必須的。
然后是進(jìn)入死循環(huán),kbhit()
函數(shù)是檢測(cè)是否有按鍵,如有按鍵返回非0值,沒(méi)有按鍵返回0;用getch()
獲取按鍵,然后用
switch case分支結(jié)構(gòu)處理不同的按鍵。
至此,我們的計(jì)時(shí)器設(shè)計(jì)完成!是不是感覺(jué)很簡(jiǎn)單?。⊥律囝^
讓我們看一下運(yùn)行結(jié)果:
下面是本程序用到的頭文件:
#include <iostream> #include <cstdlib> #include <ctime> #include <conio.h> #include <iomanip> #include <windows.h>
下面是代碼中用到的函數(shù):
void gotoxy(int x,int y)
void gotoxy(int x, int y)//定位光標(biāo),x為行坐標(biāo),y為列坐標(biāo) { COORD pos = {x,y};//(坐標(biāo) 位置); HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //得到標(biāo)準(zhǔn)處理(標(biāo)準(zhǔn)輸出處理); SetConsoleCursorPosition(hOut, pos);//設(shè)置控制臺(tái)光標(biāo)位置; }
void hidden( )
void hidden()//隱藏光標(biāo) { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(hOut,&cci); cci.bVisible=0;//賦1為顯示,賦0為隱藏 SetConsoleCursorInfo(hOut,&cci); }
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。
上一篇:C++實(shí)現(xiàn)日期類(lèi)(Date類(lèi))的方法
欄 目:C語(yǔ)言
本文標(biāo)題:C++如何實(shí)現(xiàn)簡(jiǎn)單的計(jì)時(shí)器詳解
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/1808.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 01-10如何判斷一個(gè)數(shù)是否為2的冪次方?若是,并判斷出來(lái)是多少次方
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)-用棧實(shí)現(xiàn)表達(dá)式求值的方法詳解
- 01-10使用OpenGL實(shí)現(xiàn)3D立體顯示的程序代碼
- 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
- 01-10求斐波那契(Fibonacci)數(shù)列通項(xiàng)的七種實(shí)現(xiàn)方法
- 01-10C語(yǔ)言 解決不用+、-、&#215;、&#247;數(shù)字運(yùn)算符做加法
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10如何判斷一個(gè)數(shù)是否為4的冪次方?若是,并判斷出來(lái)是多少次方
- 01-10如何查看進(jìn)程實(shí)際的內(nèi)存占用情況詳解


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10C#中split用法實(shí)例總結(jié)
- 04-02jquery與jsp,用jquery