【C言語】秒数をカウントする方法

この記事では、C言語の基本的な時間計測方法から高精度な計測方法まで、初心者にもわかりやすく解説します。

具体的なコード例を交えながら、プログラムの実行時間の計測やタイマー機能の実装、ゲームやアニメーションでの利用方法も紹介します。

目次から探す

C言語での時間計測の基本

C言語で時間を計測する方法はいくつかありますが、基本的には標準ライブラリを利用します。

ここでは、時間計測に関する基本的な知識と、具体的な関数の使い方について解説します。

標準ライブラリ <time.h> の紹介

C言語で時間を扱うための標準ライブラリが <time.h> です。

このライブラリには、時間を取得したり、時間の差を計算したりするための関数が含まれています。

以下に、主な関数とその用途を簡単に紹介します。

  • time(): 現在のカレンダー時間を取得します。
  • clock(): プログラムの実行時間を取得します。
  • difftime(): 2つの時間の差を計算します。
  • strftime(): 時間を指定した形式で文字列に変換します。

time_t 型と clock_t 型の違い

時間を扱う際に使用するデータ型として、time_t 型clock_t 型があります。

それぞれの違いについて説明します。

  • time_t 型: カレンダー時間を表すためのデータ型です。

通常、エポック(1970年1月1日 00:00:00 UTC)からの経過秒数として表現されます。

time() 関数などで使用されます。

  • clock_t 型: プログラムの実行時間を表すためのデータ型です。

通常、プロセッサのクロックチック数として表現されます。

clock() 関数などで使用されます。

time() 関数の使い方

time() 関数は、現在のカレンダー時間を取得するために使用されます。

この関数は、time_t 型の値を返します。

以下に、time() 関数の基本的な使い方を示します。

#include <stdio.h>
#include <time.h>
int main() {
    // 現在の時間を取得
    time_t current_time;
    current_time = time(NULL);
    // 取得した時間を表示
    printf("現在の時間: %ld\n", current_time);
    return 0;
}

このプログラムを実行すると、現在の時間がエポックからの経過秒数として表示されます。

例えば、以下のような出力が得られます。

現在の時間: 1633024800

この数値は、1970年1月1日 00:00:00 UTC からの経過秒数を表しています。

また、time() 関数を使って人間が読みやすい形式で時間を表示することもできます。

以下にその例を示します。

#include <stdio.h>
#include <time.h>
int main() {
    // 現在の時間を取得
    time_t current_time;
    current_time = time(NULL);
    // 取得した時間をローカル時間に変換
    struct tm *local_time;
    local_time = localtime(¤t_time);
    // ローカル時間を表示
    printf("現在のローカル時間: %s", asctime(local_time));
    return 0;
}

このプログラムを実行すると、現在のローカル時間が人間が読みやすい形式で表示されます。

例えば、以下のような出力が得られます。

現在のローカル時間: Tue Sep 30 12:00:00 2021

このように、time() 関数を使うことで、現在の時間を簡単に取得し、表示することができます。

実際の秒数カウントの実装

ここでは、実際にC言語で秒数をカウントする方法について具体的なコード例を交えて解説します。

基本的な秒数カウントの方法から、ループを使ったカウント方法まで幅広く紹介します。

基本的な秒数カウントのコード例

time() 関数を使った秒数カウント

time() 関数は、現在のカレンダー時間を取得するために使用されます。

この関数は、1970年1月1日からの経過秒数を返します。

以下に、time() 関数を使った秒数カウントの基本的な例を示します。

#include <stdio.h>
#include <time.h>
int main() {
    time_t start, end;
    
    // 現在の時間を取得
    start = time(NULL);
    if (start == (time_t)-1) {
        perror("time");
        return 1;
    }
    
    // 5秒間待機
    printf("5秒間待機します...\n");
    sleep(5);
    
    // 現在の時間を再度取得
    end = time(NULL);
    if (end == (time_t)-1) {
        perror("time");
        return 1;
    }
    
    // 経過時間を計算
    double elapsed = difftime(end, start);
    printf("経過時間: %.2f秒\n", elapsed);
    
    return 0;
}

このコードでは、time(NULL) を使って現在の時間を取得し、sleep(5) で5秒間待機します。

その後、再度 time(NULL) を使って現在の時間を取得し、difftime() 関数で経過時間を計算しています。

clock() 関数を使った秒数カウント

clock() 関数は、プロセッサ時間を計測するために使用されます。

この関数は、プログラムの実行開始からの経過クロック数を返します。

以下に、clock() 関数を使った秒数カウントの基本的な例を示します。

#include <stdio.h>
#include <time.h>
int main() {
    clock_t start, end;
    
    // 現在のクロック数を取得
    start = clock();
    if (start == (clock_t)-1) {
        perror("clock");
        return 1;
    }
    
    // 5秒間待機
    printf("5秒間待機します...\n");
    sleep(5);
    
    // 現在のクロック数を再度取得
    end = clock();
    if (end == (clock_t)-1) {
        perror("clock");
        return 1;
    }
    
    // 経過時間を計算
    double elapsed = (double)(end - start) / CLOCKS_PER_SEC;
    printf("経過時間: %.2f秒\n", elapsed);
    
    return 0;
}

このコードでは、clock() を使って現在のクロック数を取得し、sleep(5) で5秒間待機します。

その後、再度 clock() を使って現在のクロック数を取得し、経過クロック数を CLOCKS_PER_SEC で割ることで経過時間を計算しています。

ループを使った秒数カウント

次に、ループを使って秒数をカウントする方法を紹介します。

ループを使うことで、特定の処理を一定時間繰り返すことができます。

for ループを使った例

for ループを使って秒数をカウントする例を示します。

#include <stdio.h>
#include <time.h>
int main() {
    time_t start, end;
    int i;
    
    // 現在の時間を取得
    start = time(NULL);
    if (start == (time_t)-1) {
        perror("time");
        return 1;
    }
    
    // 5秒間ループを実行
    for (i = 0; i < 5; i++) {
        printf("%d秒経過\n", i);
        sleep(1);
    }
    
    // 現在の時間を再度取得
    end = time(NULL);
    if (end == (time_t)-1) {
        perror("time");
        return 1;
    }
    
    // 経過時間を計算
    double elapsed = difftime(end, start);
    printf("経過時間: %.2f秒\n", elapsed);
    
    return 0;
}

このコードでは、for ループを使って1秒ごとにメッセージを表示し、5秒間ループを実行します。

ループ終了後に経過時間を計算しています。

while ループを使った例

while ループを使って秒数をカウントする例を示します。

#include <stdio.h>
#include <time.h>
int main() {
    time_t start, current;
    
    // 現在の時間を取得
    start = time(NULL);
    if (start == (time_t)-1) {
        perror("time");
        return 1;
    }
    
    // 5秒間ループを実行
    while (1) {
        current = time(NULL);
        if (current == (time_t)-1) {
            perror("time");
            return 1;
        }
        
        double elapsed = difftime(current, start);
        if (elapsed >= 5.0) {
            break;
        }
        
        printf("%.0f秒経過\n", elapsed);
        sleep(1);
    }
    
    // 経過時間を表示
    printf("5秒経過しました\n");
    
    return 0;
}

このコードでは、while ループを使って1秒ごとにメッセージを表示し、5秒経過したらループを終了します。

ループ終了後に経過時間を表示しています。

以上が、C言語で秒数をカウントする基本的な方法とその実装例です。

次のセクションでは、高精度な時間計測方法について解説します。

高精度な時間計測

C言語での時間計測には、標準ライブラリの time.h を使った方法以外にも、より高精度な時間計測を行うための関数が存在します。

ここでは、gettimeofday() 関数clock_gettime() 関数を紹介し、それらを使った高精度な秒数カウントの実装例を示します。

gettimeofday() 関数の紹介

gettimeofday() 関数は、マイクロ秒単位での時間計測が可能な関数です。

この関数は、sys/time.h ヘッダーファイルに定義されています。

以下に gettimeofday() 関数の基本的な使い方を示します。

#include <sys/time.h>
#include <stdio.h>
int main() {
    struct timeval start, end;
    
    // 現在の時間を取得
    gettimeofday(&start, NULL);
    
    // ここに計測したい処理を記述
    
    // 現在の時間を再度取得
    gettimeofday(&end, NULL);
    
    // 経過時間を計算(秒とマイクロ秒)
    long seconds = end.tv_sec - start.tv_sec;
    long microseconds = end.tv_usec - start.tv_usec;
    double elapsed = seconds + microseconds*1e-6;
    
    printf("Elapsed time: %.6f seconds\n", elapsed);
    return 0;
}

このコードでは、gettimeofday() 関数を使ってプログラムの開始時と終了時の時間を取得し、その差分を計算して経過時間を表示しています。

clock_gettime() 関数の紹介

clock_gettime() 関数は、ナノ秒単位での時間計測が可能な関数です。

この関数は、time.h ヘッダーファイルに定義されています。

以下に clock_gettime() 関数の基本的な使い方を示します。

#include <time.h>
#include <stdio.h>
int main() {
    struct timespec start, end;
    
    // 現在の時間を取得
    clock_gettime(CLOCK_MONOTONIC, &start);
    
    // ここに計測したい処理を記述
    
    // 現在の時間を再度取得
    clock_gettime(CLOCK_MONOTONIC, &end);
    
    // 経過時間を計算(秒とナノ秒)
    long seconds = end.tv_sec - start.tv_sec;
    long nanoseconds = end.tv_nsec - start.tv_nsec;
    double elapsed = seconds + nanoseconds*1e-9;
    
    printf("Elapsed time: %.9f seconds\n", elapsed);
    return 0;
}

このコードでは、clock_gettime() 関数を使ってプログラムの開始時と終了時の時間を取得し、その差分を計算して経過時間を表示しています。

高精度な秒数カウントの実装例

ここでは、gettimeofday() 関数clock_gettime() 関数を使った高精度な秒数カウントの実装例を示します。

gettimeofday() を使った高精度な秒数カウント

#include <sys/time.h>
#include <stdio.h>
#include <unistd.h> // sleep関数を使うために必要
int main() {
    struct timeval start, end;
    
    // 現在の時間を取得
    gettimeofday(&start, NULL);
    
    // 1秒間のスリープ
    sleep(1);
    
    // 現在の時間を再度取得
    gettimeofday(&end, NULL);
    
    // 経過時間を計算(秒とマイクロ秒)
    long seconds = end.tv_sec - start.tv_sec;
    long microseconds = end.tv_usec - start.tv_usec;
    double elapsed = seconds + microseconds*1e-6;
    
    printf("Elapsed time: %.6f seconds\n", elapsed);
    return 0;
}

clock_gettime() を使った高精度な秒数カウント

#include <time.h>
#include <stdio.h>
#include <unistd.h> // sleep関数を使うために必要
int main() {
    struct timespec start, end;
    
    // 現在の時間を取得
    clock_gettime(CLOCK_MONOTONIC, &start);
    
    // 1秒間のスリープ
    sleep(1);
    
    // 現在の時間を再度取得
    clock_gettime(CLOCK_MONOTONIC, &end);
    
    // 経過時間を計算(秒とナノ秒)
    long seconds = end.tv_sec - start.tv_sec;
    long nanoseconds = end.tv_nsec - start.tv_nsec;
    double elapsed = seconds + nanoseconds*1e-9;
    
    printf("Elapsed time: %.9f seconds\n", elapsed);
    return 0;
}

これらのコード例では、1秒間のスリープを挟んで経過時間を計測しています。

gettimeofday() を使った場合はマイクロ秒単位、clock_gettime() を使った場合はナノ秒単位での計測が可能です。

これにより、より高精度な時間計測が実現できます。

実用的な応用例

C言語で秒数をカウントする方法を学んだら、次はその知識を実際のプログラムに応用してみましょう。

ここでは、プログラムの実行時間の計測、タイマー機能の実装、そしてゲームやアニメーションでの利用について解説します。

プログラムの実行時間の計測

プログラムの実行時間を計測することは、パフォーマンスの最適化やデバッグにおいて非常に重要です。

以下に、clock() 関数を使ってプログラムの実行時間を計測する方法を示します。

#include <stdio.h>
#include <time.h>
int main() {
    clock_t start, end;
    double cpu_time_used;
    // 計測開始
    start = clock();
    // 計測対象の処理
    for (int i = 0; i < 1000000; i++) {
        // 何らかの処理
    }
    // 計測終了
    end = clock();
    // 実行時間の計算
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
    printf("プログラムの実行時間: %f 秒\n", cpu_time_used);
    return 0;
}

このプログラムでは、clock() 関数を使ってプログラムの開始時刻と終了時刻を取得し、その差を計算することで実行時間を求めています。

タイマー機能の実装

次に、一定時間後に何かの処理を行うタイマー機能を実装してみましょう。

ここでは、time() 関数を使って簡単なタイマーを作成します。

#include <stdio.h>
#include <time.h>
void wait(int seconds) {
    time_t start_time, current_time;
    // 現在の時刻を取得
    time(&start_time);
    do {
        // 現在の時刻を取得
        time(¤t_time);
    } while ((current_time - start_time) < seconds);
}
int main() {
    printf("3秒待ちます...\n");
    wait(3);
    printf("時間が経過しました!\n");
    return 0;
}

このプログラムでは、wait 関数を使って指定した秒数だけ待機し、その後にメッセージを表示します。

time() 関数を使って現在の時刻を取得し、指定した秒数が経過するまでループを続けます。

ゲームやアニメーションでの利用

ゲームやアニメーションでは、時間の管理が非常に重要です。

例えば、キャラクターの動きやアニメーションのフレームレートを制御するために時間を計測することが必要です。

以下に、簡単な例を示します。

#include <stdio.h>
#include <time.h>
void game_loop() {
    time_t start_time, current_time;
    int frame_count = 0;
    // ゲームループの開始時刻を取得
    time(&start_time);
    while (frame_count < 10) {
        // 現在の時刻を取得
        time(¤t_time);
        // 1秒ごとにフレームを更新
        if ((current_time - start_time) >= 1) {
            printf("フレーム %d\n", frame_count);
            frame_count++;
            start_time = current_time; // 時刻をリセット
        }
    }
}
int main() {
    printf("ゲームループを開始します...\n");
    game_loop();
    printf("ゲームループが終了しました!\n");
    return 0;
}

このプログラムでは、1秒ごとにフレームを更新する簡単なゲームループを実装しています。

time() 関数を使って現在の時刻を取得し、1秒が経過するごとにフレームを更新します。

以上のように、C言語で秒数をカウントする方法を応用することで、さまざまな実用的なプログラムを作成することができます。

これらの例を参考にして、自分のプロジェクトに応用してみてください。

目次から探す