- ベストアンサー
デジタル時計のアルゴリズム
こんばんは。私は、プログラミングを学ぶ社会人です。現在研修中の身です。 デジタル時計のアルゴリズムを考えていまして、とりあえず無限ループさせればいいのかな?と思いました。 ところで、無限ループさせるためのアルゴリズムって、どのように書けばよろしいのでしょうか? 例えば大まかに言うと「変数TIME→0」と書いた後で、 ループ開始 | TIME+1→TIME | ループ終了 (※「|」は下に向かうフローです。) と記述し、終了条件を何も書かなければ、それで無限にループされることになるのでしょうか? ご回答よろしくお願い致します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
★Windows では無限ループはまずいです。 ・『デジタル時計』って事は自作ソフトという意味ですよね。 ・Windows はイベント・ドリブンです。 これは、何かイベントがあったときに『プロシージャ』と呼ばれる処理手続きを呼び出して 実行します。無限ループをすると自作ウインドウが CPU 100% 使用になってしまいます。 これだと他のソフトに悪影響がでてしまいます。 ・それではどうするか?→簡単です。 ・タイマーを使って時間を読み出して表示すればよいのです。 ・タイマー間隔を 1000ms に設定すると自作した『プロシージャ』関数に WM_TIMER がイベント として送られてきますので、そこで時刻の読み出しと表示を行います。 ・タイマー間隔を 100ms(1/10秒)に設定すると秒も正確に表示できます。 ・デジタル時計のアルゴリズムは次の通りです。 考え: (1)『WM_INITDIALOG』や『WM_CREATE』ルーチンで『SetTimer』関数でタイマー間隔をセット (2)『WM_TIMER』ルーチンで現在の時刻を『GetLocalTime』関数で読み出す (3)読み出した時刻を画面やダイアログのテキスト部『StaticControl』へ描画(表示)する (4)『WM_CLOSE』ルーチンで『KillTimer』関数でタイマーの破棄(後始末)する ※下に『デジタル時計』のプロシージャ関数のサンプルを載せます。 実装例: #include <windows.h> #include "resource.h" #define TID_CLOCK (1) BOOL CALLBACK ClockDialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { TCHAR szBuff[ 256 ]; SYSTEMTIME st; switch ( uMsg ){ case WM_INITDIALOG: SetTimer( hDlg, TID_CLOCK, 100, NULL ); ←100ms(0.1秒)間隔のタイマー設定 break; case WM_CLOSE: KillTimer( hDlg, TID_CLOCK ); ←タイマー破棄 EndDialog( hDlg, IDOK ); break; case WM_TIMER: GetLocalTime( &st ); ←時刻を読み出す wsprintf( szBuff, TEXT("%2d時%02d分%02d秒"), st.wHour, st.wMinute, st.wSecond ); SetWindowText( hDlg, szBuff ); ←表示 break; default:return( FALSE ); } return( TRUE ); } extern int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { DialogBox( hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, ClockDialogProc ); return( 0 ); } 最後に: ・上記のサンプルは 0.1 秒間隔で現在の時刻を読み出して、ダイアログのタイトルバーに 『23時59分59秒』という時刻を表示し続けます。 ・以上。おわり。
その他の回答 (2)
- MrBan
- ベストアンサー率53% (331/615)
アルゴリズムの勉強で、フローの記法について質問されているようですので、 「終了条件のないループは無限ループ」という認識は正しいです。 というのが質問者さまへの回答になります。 以下、余談。 大抵の環境では、実装手段は変わっても本質的なアルゴリズムは変わらないです。 ゆえに「考え方」を知るのは有効で、かつ大事です。 実装についても例えばC++なら、 for(;;){ /*何か*/ } while(true){ /*何か*/ } 等が典型的な無限ループの記法で、WindowsでもLinuxでも、μITRONでもこれで無限ループできます。 Windowsで別スレッドにSleep挟んでループするもよし。 イベントドリブンも、概念は別にして実装レベルで極論すれば、 メッセージループ(GetMessage~DispatchMessage)を挟んで回ってるだけです。 「デジタル時計」としての本質的なアルゴリズムは一緒です。 # 実装方法は勿論環境毎に結構違うのですけど…それは別次元のお話。 無限ループがお行儀悪いといわれるのは一般にUIの話であって、 環境次第でソフトにUIがあるとも限りませんし、 本物のデジタル時計(置時計など)の中にも組込ソフトが動いてますが、 これらは無限ループでタスクが回り続けてるはずです(終了という概念はないので)。
お礼
ご回答ありがとうございます。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★アルゴリズムですか? ・回答者 No.1 です。 ・前回の回答は Windows での GUI による実装例でした。 ・カテゴリが『その他(プログラミング)』でしたね。 考え: ・基本はある一定時間の間隔で、現在の時刻を読み出すためにループさせます。 ・昔の MS-DOS という OS ならば単純に無限ループを組んで、そのループ内でキー入力があるかどうか を調査します。もし、キー入力バッファにキー入力情報が入っていれば、無限ループから抜けるように 終了条件を記述しました。 ・終了条件がないと当然、ずっと無限ループを繰り返します。→プログラムを強制終了しない限りは 終了できないでしょう。→お行儀が悪い、または常駐タイプのデジタル時計ですね。 最後に: ・どんな言語で、どの OS で、ウインドウタイプ(GUI)か、コマンドラインタイプ(CUI)かを教えてくれないと これ以上のアドバイスは不能です。→環境によりアルゴリズムがいろいろと変ります。 ・以上。おわり。
お礼
またのご回答、ありがとうございました。
お礼
これほど詳しいご回答、恐縮致します。 今は自作で何かを作れるレベルではなく、ほんとに単純に、デジタル時計の場合のアルゴリズムの概念を教えていただければよかったのですが(^^;。ご丁寧にお答え頂き、大変申し訳ありません。 これはこれで、実際に作る講義に入ったときに参考にさせて頂きます。 本当にありがとうございました。