Menu
Coddy logo textTech

オブジェクトとしての構造体

CoddyのCジャーニー「Object Oriented Programming」セクションの一部 — レッスン 6/61。

オブジェクト指向言語では、オブジェクトとは、データ(状態)と、そのデータを操作する関数(メソッド)をまとめた実体です。C言語には組み込みのオブジェクトはありませんが、構造体(structs)と関数(functions)を使用することで、同じ概念を実現できます。

構造体(struct)をオブジェクトの「データ」部分と考えてください。それは状態、つまりオブジェクトが現在何であるかを定義する値を保持します:

typedef struct {
    int value;
} Counter;

この Counter 構造体は、単一の状態(現在の値)を持つエンティティを表します。これに振る舞いを与えるために、この構造体をパラメータとして受け取る関数を記述します:

void counter_increment(Counter *c) {
    c->value++;
}

int counter_get(Counter *c) {
    return c->value;
}

これらの関数はメソッドのように動作します。これらは特にCounterデータに対して操作を行います。構造体を関数に渡すことで、counter.increment()を呼び出したときに他の言語が自動的に行うことをシミュレートしています。

int main() {
    Counter my_counter = {0};
    counter_increment(&my_counter);
    printf("%d\n", counter_get(&my_counter)); // 出力: 1
    return 0;
}

命名規則 typename_actioncounter_increment など)は、コードを整理し、関数がどの構造体に属しているかを明確にするのに役立ちます。このパターンは、C言語におけるオブジェクト指向プログラミングの基礎となります。

challenge icon

チャレンジ

簡単

構造体を振る舞いを持つオブジェクトとして扱う、シンプルな Counter モジュールを作成しましょう。データとそれを操作する関数をバンドルするパターンを練習するために、コードを3つのファイルに整理します。

以下の3つのファイルを作成します:

  • counter.h: 1つの int value メンバを持つ Counter 構造体を宣言するヘッダーファイルです。また、カウンターの「メソッド」として機能する2つの関数、counter_increment(Counter へのポインタを受け取り、その値を1増やします)と counter_get(Counter へのポインタを受け取り、その現在の値を返します)も宣言してください。インクルードガードには COUNTER_H というシンボルを使用してください。
  • counter.c: 両方の関数を実装するソースファイルです。ヘッダーファイルをインクルードすることを忘れないでください。
  • main.c: Counter を作成し、それに対して操作を行い、結果を表示するメインファイルです。

2つの整数入力を受け取ります。カウンターの開始値と、それをインクリメントする回数です。

メインファイルで、開始値を使用して Counter を初期化し、指定された回数だけ counter_increment を呼び出します。最後に、counter_get を使用して最終的な値を取得し、表示します。

結果を次の形式で出力してください:

Final value: {result}

例えば、開始値が 5 でインクリメントが 3 回の場合、出力は次のようになります:

Final value: 8

チートシート

C言語では、構造体(データ)と、それらの構造体を操作する関数(振る舞い)を組み合わせることで、オブジェクト指向プログラミングをシミュレートできます。

状態を保持するための構造体を定義します:

typedef struct {
    int value;
} Counter;

構造体をパラメータとして受け取ることで、「メソッド」として機能する関数を作成します:

void counter_increment(Counter *c) {
    c->value++;
}

int counter_get(Counter *c) {
    return c->value;
}

構造体と関数を組み合わせて使用します:

Counter my_counter = {0};
counter_increment(&my_counter);
printf("%d\n", counter_get(&my_counter)); // 出力: 1

typename_action(例:counter_increment)という命名規則は、コードを整理し、関数がどの構造体を操作するのかを明確にするのに役立ちます。

自分で試してみよう

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

int main() {
    // 入力を読み込む
    int starting_value;
    int num_increments;
    scanf("%d", &starting_value);
    scanf("%d", &num_increments);
    
    // TODO: Counterを作成し、starting_valueで初期化する
    
    // TODO: 指定された回数だけcounter_incrementを呼び出す
    
    // TODO: counter_getを使用して最終的な値を取得し、表示する
    // 出力形式: "Final value: {result}"
    
    return 0;
}
quiz icon腕試し

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

Object Oriented Programmingのすべてのレッスン