ヘルパーメソッド
CoddyのCジャーニー「Object Oriented Programming」セクションの一部 — レッスン 10/61。
これまで、構造体データを変更する関数(player_take_damage のような)や、単にそれを表示する関数を見てきました。しかし、もう一つの重要なカテゴリがあります。それは、何も変更せずに構造体のメンバから派生した値を計算する関数です。
幅と高さを保持する Rectangle struct を考えてみましょう。面積は保存されず、必要に応じて計算されます:
typedef struct {
double width;
double height;
} Rectangle;
double rectangle_area(const Rectangle *self) {
return self->width * self->height;
}
double rectangle_perimeter(const Rectangle *self) {
return 2 * (self->width + self->height);
}
これらはヘルパーメソッドです。これらは構造体の既存のデータを受け取り、新しい値を生成します。読み取りのみを行い、書き込みは行わないため、constポインタを使用している点に注目してください。計算結果は構造体に格納されるのではなく、戻り値として返されます。
Rectangle box = {5.0, 3.0};
printf("Area: %.1f\n", rectangle_area(&box)); // 15.0
printf("Perimeter: %.1f\n", rectangle_perimeter(&box)); // 16.0
このパターンは、構造体を軽量に保ちます。必須のデータのみを保存し、それ以外はすべて必要な時に計算するようにします。また、派生した値が常に現在の状態と一致することも保証されます。
チャレンジ
簡単保存されたデータから派生した値を計算する Circle モジュールを作成しましょう。構造体のメンバーを変更せずに結果を計算する関数である、ヘルパーメソッドの作成を練習します。
3つのファイルを作成します:
circle.h: 1つのdouble radiusメンバーを持つCircle構造体を宣言します。また、2つのヘルパーメソッドを宣言します:circle_area— Circle へのconstポインタを受け取り、面積を返しますcircle_circumference— Circle へのconstポインタを受け取り、円周を返します
CIRCLE_Hを使用してインクルードガードを設定してください。circle.c: 両方のヘルパーメソッドを実装します。計算には、円周率の値として3.14159を使用してください。面積の公式はpi * radius * radiusで、円周の公式は2 * pi * radiusです。どちらの関数も半径を読み取るだけで、決して変更しないでください。main.c: Circle を作成し、ヘルパーメソッドを使用してそのプロパティを計算して表示します。
1つの入力を受け取ります:円の radius(double型)。
メインファイルで、与えられた半径で Circle を初期化し、ヘルパーメソッドを使用して面積と円周を計算して出力してください。
結果を次の形式で出力してください:
Area: {area}
Circumference: {circumference}両方の値に %.2f を使用して、小数点以下2桁まで表示してください。
例えば、半径が 5.0 の場合、出力は次のようになります:
Area: 78.54
Circumference: 31.42チートシート
関数は、構造体を変更することなく、構造体のメンバから派生した値を計算できます。これらはヘルパーメソッドと呼ばれます。
ヘルパーメソッドは、データの読み取りのみを行い、書き込みは行わないため、const ポインタを使用します:
typedef struct {
double width;
double height;
} Rectangle;
double rectangle_area(const Rectangle *self) {
return self->width * self->height;
}
double rectangle_perimeter(const Rectangle *self) {
return 2 * (self->width + self->height);
}
ヘルパーメソッドの使用例:
Rectangle box = {5.0, 3.0};
printf("Area: %.1f\n", rectangle_area(&box)); // 15.0
printf("Perimeter: %.1f\n", rectangle_perimeter(&box)); // 16.0
このパターンは、必須のデータのみを保存し、必要に応じて派生値を計算することで構造体を軽量に保ち、現在の状態との整合性を確保します。
自分で試してみよう
#include <stdio.h>
#include "circle.h"
int main() {
double radius;
scanf("%lf", &radius);
// TODO: 与えられた半径で Circle 構造体を作成する
// TODO: circle_area と circle_circumference ヘルパーメソッドを使用する
// 結果を計算して表示する
// 出力形式:
// printf("Area: %.2f\n", ...);
// printf("Circumference: %.2f\n", ...);
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。