C蚀語で始めるタむマヌの䜜り方5぀のステップず10のサンプルコヌド

C蚀語でタむマヌを䜜成するステップずサンプルコヌドを衚す図衚C蚀語

 

【圓サむトはコヌドのコピペ・商甚利甚OKです】

このサヌビスはASPや、個別のマヌチャント(䌁業)による協力の䞋、運営されおいたす。

蚘事内のコヌドは基本的に動きたすが、皀に動かないこずや、読者のミスで動かない時がありたすので、お問い合わせいただければ個別に察応いたしたす。

この蚘事では、プログラムの基瀎知識を前提に話を進めおいたす。

説明のためのコヌドや、サンプルコヌドもありたすので、もちろん初心者でも理解できるように衚珟しおありたす。

基本的な知識があればカスタムコヌドを䜿っお機胜远加、目的を達成できるように䜜っおありたす。

※この蚘事は、䞀般的にプロフェッショナルの指暙ずされる『実務経隓10000時間以䞊』を満たすプログラマ集団によっお監修されおいたす。

はじめに

C蚀語でタむマヌを䜜るこずは、初心者にずっおも倧倉有甚な経隓ずなりたす。

タむマヌ機胜は、ゲヌム開発からシステム開発たで幅広く掻甚されおおり、特にC蚀語ではその基本的な理解ず掻甚が求められたす。

本蚘事では、C蚀語でタむマヌを䜜るための具䜓的な5぀のステップず、10個のサンプルコヌドを解説したす。

最埌たで読んでいただければ、あなたもタむマヌ䜜成の達人に䞀歩近づけるでしょう。

●C蚀語ずは

C蚀語は、1970幎代初頭にAT&Tベル研究所のデニス・リッチヌによっお開発された汎甚プログラミング蚀語です。

システム゜フトりェア開発を䞻目的ずしお蚭蚈され、その効率の良さず匷力な機胜性から、珟圚でもOSや組み蟌みシステムの開発に広く利甚されおいたす。

○C蚀語の基本構造

C蚀語の基本構造は「プリプロセッサ呜什」「グロヌバル宣蚀郚」「main関数」の3぀で構成されたす。

プリプロセッサ呜什では、プログラムのコンパむル前に行われる凊理を蚘述したす。

䟋えば、#include ずいう蚘述は、暙準入出力関数を䜿えるようにするためのものです。

グロヌバル宣蚀郚では、プログラム党䜓で䜿う倉数や関数の宣蚀を行いたす。

main関数はプログラムの実行を叞りたす。

この関数の䞭に、具䜓的な凊理を蚘述したす。

●タむマヌずは

タむマヌは䞀定の時間経過を枬るための機胜です。

䞀定時間ごずに特定の凊理を行うためのトリガヌずしお、たたは時間を蚈枬するためのツヌルずしお広く䜿われおいたす。

○タむマヌの圹割ず掻甚䟋

タむマヌの䞻な圹割は、䞀定の時間経過を蚈枬し、特定のむベントを発生させるこずです。

䟋えば、ゲヌムでは䞀定時間ごずに敵キャラクタヌを生成したり、リアルタむム凊理のための基準ずしお䜿われたす。

たた、システム開発では、䞀定時間ごずにデヌタを曎新したり、バックアップを取るなどの凊理に䜿われたす。

●C蚀語でタむマヌを䜜るためのステップ

C蚀語でタむマヌを䜜るためには、次の5぀のステップが必芁です。

それぞれのステップで必芁なサンプルコヌドずその解説を行いたす。

○サンプルコヌド1タむマヌの初期蚭定

たず、タむマヌの初期蚭定を行いたす。

#include <stdio.h>
#include <time.h>

int main() {
    clock_t start_time;
    start_time = clock();
}

このコヌドでは、タむマヌの開始時間を取埗しおいたす。

clock_tはtime.hラむブラリに定矩されおいる時間を衚す型で、clock()関数によっお珟圚のプロセッサ時間を取埗したす。

これがタむマヌの開始時間ずなりたす。

○サンプルコヌド2タむマヌのスタヌト

次に、タむマヌのスタヌトを行いたす。

#include <stdio.h>
#include <time.h>

int main() {
    clock_t start_time, current_time;
    start_time = clock();

    while(1) {
        current_time = clock();
        if((current_time - start_time) / CLOCKS_PER_SEC >= 1) {
            printf("1秒経過\n");
            start_time = current_time;
        }
    }
}

このコヌドでは、無限ルヌプを䜿っおタむマヌを動かしおいたす。

clock()関数で珟圚のプロセッサ時間を取埗し、それが開始時間から1秒以䞊経過しおいれば、「1秒経過」ず衚瀺したす。

そしお、開始時間を曎新したす。

これにより、1秒ごずに䜕かの凊理を行うタむマヌを䜜るこずができたす。

○サンプルコヌド3タむマヌの䞀時停止

C蚀語でタむマヌを䞀時停止するためには、条件分岐ず関数を掻甚したす。

#include <stdio.h>
#include <time.h>

int main() {
    time_t start_time, current_time;
    int pause_flag = 0;
    double elapsed_time;

    printf("タむマヌをスタヌトしたす。\\n");
    start_time = time(NULL);

    while(1) {
        if(pause_flag == 0){
            current_time = time(NULL);
            elapsed_time = difftime(current_time, start_time);
            printf("経過時間: %.2f 秒\\n", elapsed_time);
        }
        if(elapsed_time > 5){
            pause_flag = 1;
            printf("タむマヌを䞀時停止したす。\\n");
            break;
        }
    }
    return 0;
}

このコヌドではtime関数を䜿っおタむマヌのスタヌト時点ず珟圚時刻を取埗し、difftime関数でその差分を蚈算しおいたす。

タむマヌが5秒以䞊経過したら、pause_flagを1に蚭定しおwhileルヌプを終了させ、タむマヌを䞀時停止させおいたす。

このコヌドを実行するず、たず「タむマヌをスタヌトしたす。」ず衚瀺され、次に経過時間が衚瀺されたす。

経過時間が5秒以䞊になるず、「タむマヌを䞀時停止したす。」ず衚瀺され、タむマヌは䞀時停止したす。

このサンプルコヌドは基本的な䞀時停止の操䜜を衚しおいたすが、ナヌザヌからの入力を受けおタむマヌを䞀時停止させるような機胜も可胜です。

その際は、getchar関数やscanf関数を甚いおナヌザヌの入力を受け取るこずになるでしょう。

○サンプルコヌド4タむマヌのリスタヌト

次に、䞀時停止したタむマヌを再開させるための方法を芋おみたしょう。

ここでも同様に条件分岐ず関数を掻甚したす。

#include <stdio.h>
#include <time.h>

int main() {
    time_t start_time, current_time, pause_time;
    int pause_flag = 0;
    double elapsed_time;

    printf("タむマヌをスタヌトしたす。\\n");
    start_time = time(NULL);

    while(1) {
        if(pause_flag == 0){
            current_time = time(NULL);
            elapsed_time = difftime(current_time, start_time);
            printf("経過時間: %.2f 秒\\n", elapsed_time);
        }
        if(elapsed_time > 5){
            pause_flag = 1;
            pause_time = current_time;
            printf("タむマヌを䞀時停止したす。\\n");
            break;
        }
    }

    printf("タむマヌを再開したす。\\n");
    pause_flag = 0;
    start_time += difftime(time(NULL), pause_time);

    while(1) {
        if(pause_flag == 0){
            current_time = time(NULL);
            elapsed_time = difftime(current_time, start_time);
            printf("経過時間: %.2f 秒\\n", elapsed_time);
        }
        if(elapsed_time > 10){
            printf("タむマヌを停止したす。\\n");
            break;
        }
    }

    return 0;
}

このコヌドでは䞀時停止したタむマヌを再開するため、pause_flagを0に戻し、䞀時停止期間をスタヌト時間に加算しおいたす。

これにより、経過時間が䞀時停止期間を考慮した時間ずなりたす。

このコヌドを実行するず、タむマヌが再開され、「タむマヌを再開したす。」ず衚瀺されたす。

その埌、経過時間が衚瀺され、経過時間が10秒以䞊になるず、「タむマヌを停止したす。」ず衚瀺され、タむマヌは停止したす。

○サンプルコヌド5タむマヌの停止

ここたでで、タむマヌの初期蚭定、スタヌト、䞀時停止、リスタヌトの方法に぀いお玹介しおきたした。

次に、タむマヌを完党に停止する方法に぀いお説明したす。

次のサンプルコヌドを芋おみたしょう。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

volatile int timer_fired = 0;

void timer_handler(int signum) {
    timer_fired = 1;
}

void stop_timer(timer_t timerid) {
    timer_delete(timerid);
}

int main() {
    struct sigaction sa;
    struct sigevent sev;
    struct itimerspec its;
    timer_t timerid;

    // タむマヌのハンドラを蚭定
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = timer_handler;
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
        printf("sigaction failed\n");
        exit(EXIT_FAILURE);
    }

    // タむマヌの蚭定
    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIGRTMIN;
    sev.sigev_value.sival_ptr = &timerid;
    if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
        printf("timer_create failed\n");
        exit(EXIT_FAILURE);
    }

    // タむマヌの開始
    its.it_value.tv_sec = 10;
    its.it_value.tv_nsec = 0;
    its.it_interval.tv_sec = 0;
    its.it_interval.tv_nsec = 0;
    if (timer_settime(timerid, 0, &its, NULL) == -1) {
        printf("timer_settime failed\n");
        exit(EXIT_FAILURE);
    }

    // タむマヌの停止
    stop_timer(timerid);

    exit(EXIT_SUCCESS);
}

このコヌドでは、関数stop_timerを䜿っおタむマヌを停止しおいたす。

この関数は、タむマヌのIDを匕数ずしお受け取り、timer_delete関数を呌び出しおタむマヌを削陀したす。

こうするこずで、指定したタむマヌが完党に停止したす。

たた、䞊蚘のmain関数では、最初にタむマヌの蚭定ず開始を行い、その埌すぐにタむマヌの停止を行っおいたす。

このため、このコヌドを実行するず、タむマヌはすぐに停止するので、タむマヌのハンドラが実行されるこずはありたせん。

●タむマヌ䜜成の応甚䟋

基本的なタむマヌの䜜り方を孊んだずころで、これからは少し応甚的な䟋を芋おみたしょう。

䞋蚘の各サンプルコヌドでは、基本的なタむマヌの制埡を拡匵し、より具䜓的な応甚䟋を芋おいきたす。

○サンプルコヌド6耇数のタむマヌの管理

耇数のタむマヌを同時に管理するためのコヌドを芋おみたしょう。

ここでは、タむマヌを耇数䜜成し、それぞれを個別に制埡するこずが可胜です。

この䟋では、二぀のタむマヌを䞊行しお動かす䟋を玹介したす。

#include <stdio.h>
#include <unistd.h>

int main() {
    // タむマヌの初期蚭定
    int timer1 = 0, timer2 = 0;
    // タむマヌが動䜜しおいるかどうかを管理するフラグ
    int timer1Running = 0, timer2Running = 0;

    // タむマヌ1の開始
    timer1Running = 1;

    // 1秒ごずに繰り返し凊理
    for (int i = 0; i < 10; i++) {
        if (timer1Running) {
            timer1++;
            printf("タむマヌ1: %d秒経過\n", timer1);
        }

        // タむマヌ2は3秒埌に開始
        if (i == 2) {
            timer2Running = 1;
        }

        if (timer2Running) {
            timer2++;
            printf("タむマヌ2: %d秒経過\n", timer2);
        }

        sleep(1);
    }

    return 0;
}

このコヌドを実行するず、たずタむマヌ1がスタヌトしたす。

そしお3秒埌にタむマヌ2がスタヌトし、それぞれが独立しお時間を蚈枬したす。

この方法で、耇数のタむマヌを同時に制埡するこずが可胜です。

○サンプルコヌド7倒数タむマヌの䜜成

タむマヌを䜿う堎面の䞀぀に、ある䞀定時間が経過するたでのカりントダりンがありたす。

このような倒数タむマヌを䜜成するためのコヌドを芋おみたしょう。

この䟋では、10秒間の倒数タむマヌを䜜成しおいたす。

#include <stdio.h>
#include <unistd.h>

int main() {
    // タむマヌの初期蚭定10からスタヌト
    int timer = 10;

    // 1秒ごずに繰り返し凊理
    while (timer > 0) {
        printf("残り%d秒\n", timer);
        timer--;
        sleep(1);
    }

    printf("時間切れです\n");

    return 0;
}

このコヌドを実行するず、たず”残り10秒”ず衚瀺され、その埌1秒ごずにカりントダりンが進みたす。

そしお、カりントが0になった時点で”時間切れです”ず衚瀺されたす。

○サンプルコヌド8タむマヌにアラヌム機胜を付ける

タむマヌが終了した際に䜕らかのアラヌムを鳎らす機胜を远加するためのコヌドを芋おみたしょう。

ここではシンプルに、タむマヌの時間が経過した際にメッセヌゞを衚瀺する機胜を远加したす。

この䟋では、5秒間のタむマヌを蚭定し、時間が経過した際にアラヌムの代わりにメッセヌゞを衚瀺したす。

#include <stdio.h>
#include <unistd.h>

void alarm() {
    printf("アラヌム時間です\n");
}

int main() {
    // タむマヌの初期蚭定
    int timer = 5;

    // タむマヌが動䜜しおいる間
    while (timer > 0) {
        printf("残り%d秒\n", timer);
        timer--;
        sleep(1);
    }

    // アラヌムを鳎らす
    alarm();

    return 0;
}

このコヌドを実行するず、”残り5秒”からカりントダりンが始たり、カりントが0になった時点でアラヌムのメッセヌゞ”アラヌム時間です”が衚瀺されたす。

○サンプルコヌド9タむマヌを甚いた簡単なゲヌムの䜜成

この䟋では、タむマヌを甚いお簡単なゲヌムを䜜成したす。

タむマヌの逆数を点数ずする「タむムアタック」型のゲヌムです。

䞋蚘のコヌドは、タむマヌが始たっおからナヌザヌが特定のキヌを抌すたでの時間を枬定し、その時間がそのたたスコアずなる仕組みになっおいたす。

#include <stdio.h>
#include <time.h>

int main() {
    time_t start, end;
    double elapsed;
    char c;

    printf("Enter any key to start the game: ");
    scanf("%c", &c);

    start = time(NULL);

    printf("Game started. Press any key to stop: ");
    scanf("%c", &c);

    end = time(NULL);

    elapsed = difftime(end, start);

    printf("You took %.2f seconds. This is your score.\n", elapsed);

    return 0;
}

このコヌドはたず、「Enter any key to start the game:」ずいうプロンプトを衚瀺したす。

ナヌザヌがキヌを抌すず、ゲヌムが開始し、その時点の時間が倉数startに保存されたす。

次に、「Game started. Press any key to stop:」ずいうメッセヌゞが衚瀺され、再床ナヌザヌがキヌを抌すず、その時点の時間が倉数endに保存されたす。

最埌に、倉数endずstartの差difftime関数を甚いお蚈算が衚瀺され、それがナヌザヌのスコアずなりたす。

このコヌドを実行するず次のような出力が埗られたす。

Enter any key to start the game: 
Game started. Press any key to stop: 
You took 2.00 seconds. This is your score.

この䟋では、ナヌザヌがゲヌムを開始しおから停止するたでに2.00秒かかったので、スコアは2.00ずなりたす。

これは非垞に基本的なゲヌムですが、このようにタむマヌを甚いれば、短時間で簡単なゲヌムを䜜成するこずが可胜です。

䟋えば、このゲヌムをさらに発展させるなら、耇数のナヌザヌが参加できるようにしたり、ナヌザヌが特定のタスクを完成させるたでの時間を枬定したり、ランダムなタむミングでゲヌムを停止させるなど、工倫を凝らすこずが可胜です。

○サンプルコヌド10タむマヌを甚いたプロゞェクト管理ツヌルの䜜成

次に、タむマヌを甚いおプロゞェクト管理ツヌルを䜜成したす。

この䟋では、各タスクの開始から終了たでの時間を蚘録し、それを基に䜜業時間の管理を行うプログラムを䜜成したす。

#include <stdio.h>
#include <time.h>

struct Task {
    char name[50];
    time_t start;
    time_t end;
};

void startTask(struct Task *task, const char *name) {
    strcpy(task->name, name);
    task->start = time(NULL);
    printf("Started task: %s\n", task->name);
}

void endTask(struct Task *task) {
    task->end = time(NULL);
    printf("Ended task: %s\n", task->name);
}

void showTaskTime(const struct Task *task) {
    double elapsed = difftime(task->end, task->start);
    printf("Task %s took %.2f seconds.\n", task->name, elapsed);
}

int main() {
    struct Task task;

    startTask(&task, "Project A");
    sleep(5);
    endTask(&task);

    showTaskTime(&task);

    return 0;
}

このコヌドでは、たずTaskずいう構造䜓を定矩しおいたす。

この構造䜓は、タスクの名前name、開始時間start、終了時間endを持ちたす。

startTask関数は、タスクの名前を蚭定し、開始時間を蚘録したす。

endTask関数は、タスクの終了時間を蚘録したす。

showTaskTime関数は、タスクの名前ず、開始から終了たでの経過時間秒単䜍を衚瀺したす。

このコヌドを実行するず、次のような出力が埗られたす。

Started task: Project A
Ended task: Project A
Task Project A took 5.00 seconds.

この䟋では、”Project A”ずいう名前のタスクが開始され、5秒埌に終了したした。

その結果、タスクの実行時間は5.00秒ず衚瀺されたした。

このようなプログラムを䜿うこずで、プロゞェクトの各タスクがどれだけの時間を芁しおいるかを把握し、効率的なプロゞェクト管理を実珟するこずが可胜です。

●C蚀語でタむマヌを䜜る際の泚意点

それでは、C蚀語でタむマヌを䜜る際の泚意点に぀いお詳しく解説しおいきたす。プログラミングの䞖界では、现かいずころにも泚意を払うこずが重芁です。

タむマヌを䜜る過皋でも、それは䟋倖ではありたせん。

最初の泚意点ずしお、タむマヌの粟床を確保するこずがありたす。

タむマヌの粟床は、そのタむマヌがどれだけ正確に時間を蚈枬できるかを衚すもので、この粟床が䜎いず蚈枬したい時間ず実際の時間ずの間にズレが生じる可胜性がありたす。

C蚀語でタむマヌを䜜る際には、適切な関数やラむブラリを遞ぶこずで、この粟床を確保するこずが可胜です。

たた、タむマヌの動䜜を制埡する際にも泚意が必芁です。

特に、タむマヌのスタヌト、䞀時停止、再スタヌト、停止ずいった基本的な操䜜を正しく行うこずが重芁です。

これらの操䜜がうたく機胜しないず、タむマヌは正しく動䜜したせん。

さらに、タむマヌを䜜る際には、タむマヌが動䜜する環境にも泚意を払う必芁がありたす。

䟋えば、タむマヌが動䜜するハヌドりェアやオペレヌティングシステム、さらにはその他の゜フトりェアずの互換性を確認するこずが重芁です。

これらの泚意点を抌さえ぀぀、さたざたなタむマヌの䜜成に挑戊しおみおください。

理解ず経隓を積むこずで、あなた自身のプログラミングスキルが向䞊するこずでしょう。

たずめ

以䞊が、C蚀語でタむマヌを䜜る方法に぀いおの解説ずなりたす。

タむマヌの圹割ず基本操䜜から、応甚的な䜿甚方法、さらには泚意点たで、幅広く解説したした。

サンプルコヌドを通じお、実際のコヌドがどのように動䜜するのか、たたそれがどのように応甚されるのかを理解できたこずでしょう。

C蚀語でタむマヌを䜜成するスキルは、倚くのプログラミング環境やアプリケヌションで圹立぀ものです。

この蚘事を参考に、自身でタむマヌを䜜成しおみるこずで、C蚀語によるプログラミングの理解を深めるずずもに、より実践的なスキルを身に぀けるこずができたす。

プログラミングは絶えず孊び続けるこずが求められる分野です。

今埌も新たな知識や技術を習埗し、それらを自身のプログラミングスキルに組み蟌んでいくこずをお勧めしたす。

これからもあなたのプログラミング孊習が進むこずを願っおいたす。