Menu
Coddy logo textTech

Const の妥当性

CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 8/61。

メソッドとして機能する関数を書くとき、オブジェクトを変更するもの(player_take_damageなど)もあれば、何も変更せずにデータを読み取るだけのものもあります。constキーワードを使うと、この区別をコンパイラーレベルで強制できます。

ポインタパラメータに const を付けることで、そのポインタが指すデータを function が変更しないことを保証します。誤って member を変更しようとすると、コンパイラはエラーを生成します。

typedef struct {
    int x;
    int y;
} Point;

// この関数はポイントを読み取ることしかできません
void point_print(const Point *self) {
    printf("(%d, %d)\n", self->x, self->y);
    // self->x = 10;  // ERROR: constポインタを通しては変更できません
}

// この関数はポイントを変更できます
void point_move(Point *self, int dx, int dy) {
    self->x += dx;
    self->y += dy;
}

const Point *self パラメータは、point_print が「getter」、つまり読み取り専用の操作であることを、コンパイラと他のプログラマーの両方に伝えます。これはconst correctnessと呼ばれ、変更が必要ない箇所ではどこでもconstを使用することを意味します。

この練習はバグを早期に発見します。display 関数を書いていて誤ってフィールドを変更すると、コンパイラーはバグがプログラムに入り込むのを許すのではなく、すぐに停止します。

challenge icon

チャレンジ

簡単

Temperature モジュールを作成しましょう。このモジュールは温度の値を保持し、読み取り専用と変更操作の両方を提供します。これにより、データを単に読み取る関数とデータを変更する関数を明確に区別するための const ポインターの使い方を練習できます。

3つのファイルを作成します。

  • temperature.h:単一の double celsius member を持つ Temperature 構造体を Declare します。また、3つの関数も Declare します。
    • temp_display:Temperature への const ポインターを受け取り、Current 温度を出力します(読み取り専用)
    • temp_adjust:Temperature への通常のポインターと double の amount を受け取り、amount を celsius に加えます(変更)
    • temp_to_fahrenheit:Temperature への const ポインターを受け取り、Fahrenheit に conversion した値を返します(読み取り専用)
    TEMPERATURE_H シンボルで include guards を使用します。
  • temperature.c:3つの関数すべてを Implement します。temp_display 関数は Current: {celsius}C の Format で出力します。temp_to_fahrenheit 関数は celsius * 9.0 / 5.0 + 32.0 を返します。const ポインターを使用する関数は、構造体の data を MODIFY できないことに注意してください。
  • main.c:Temperature を Create し、操作を実行して、結果を表示します。

2つの入力を受け取ります。1つ目はinitial celsius value(double として)、2つ目はadjustment amount(double として)です。

main ファイルでは、次の操作を行います。

  1. initial celsius value で Temperature を initialize します
  2. temp_display を Call して開始時の温度を表示します
  3. temp_adjust を Call して adjustment amount によって温度を MODIFY します
  4. temp_display を again Call して更新後の温度を表示します
  5. temp_to_fahrenheit を使用して Fahrenheit conversion を Print します

結果を次の Format で Print します。

Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}F

すべての温度の値には %.1f を使用し、小数点以下1桁で表示します。

たとえば、initial value が 20.0、adjustment が 5.0 の場合、出力は次のようになります。

Current: 20.0C
Current: 25.0C
Fahrenheit: 77.0F

自分で試してみよう

#include <stdio.h>
#include "temperature.h"

int main() {
    double initial_celsius, adjustment;
    scanf("%lf", &initial_celsius);
    scanf("%lf", &adjustment);
    
    // TODO: Temperature構造体を作成し、initial_celsiusで初期化する
    
    // TODO: temp_displayを呼び出して開始温度を表示する
    
    // TODO: temp_adjustを呼び出してadjustmentの量だけ温度を変更する
    
    // TODO: temp_displayを再度呼び出して更新された温度を表示する
    
    // TODO: temp_to_fahrenheitを使用して華氏変換を出力する
    // 形式: "Fahrenheit: %.1fF\n"
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Cオンラインコンパイラ