Menu
Coddy logo textTech

構造体の値渡し

CoddyのCジャーニー「Logic & Flow」セクションの一部 — レッスン 46/63。

構造体や構造体へのポインタの扱い方を理解したところで、構造体全体を関数に渡す方法を学ぶ時が来ました。構造体をパラメータとして関数に渡すと、C言語は値渡し(pass-by-value)を使用します。これは、関数が構造体の完全なコピーを受け取ることを意味します。

構造体パラメータを受け取る関数の構文は次のとおりです。

void functionName(struct StructureName parameterName) {
    // 関数本体
}

おなじみの Point 構造体を例として使用します:

void printPoint(struct Point p) {
    printf("Point coordinates: (%d, %d)\n", p.x, p.y);
}

理解すべき重要な概念は、関数内で行った構造体へのいかなる変更も、呼び出し元の関数にある元の構造体には影響を与えないということです。これは、関数がデータの独自のコピーを使用して動作するためです。

このアプローチは、元のデータを誤って変更するリスクを冒さずに、構造体(struct)データを読み取ったり表示したりしたい場合に便利です。ただし、大きな構造体をコピーすることは、メモリやパフォーマンスの面で非効率になる可能性があることに注意してください。

challenge icon

チャレンジ

簡単

構造体を値渡しで関数に渡す方法を示すCプログラムを作成してください。プログラムの内容は以下の通りです:

  1. 以下のメンバを持つ Rectangle という名前の struct を定義します:
    • 長方形の幅を格納する整数型の width
    • 長方形の高さを格納する整数型の height
    • 長方形の色を格納するサイズ15の文字配列 color
  2. 以下の処理を行う displayRectangle という名前の関数を記述します:
    • Rectangle 構造体をパラメータとして受け取る(値渡し)
    • 長方形の情報を以下の正確な形式で出力する:
      • Rectangle Details:
      • Width: [width]
      • Height: [height]
      • Color: [color]
      • Area: [area]
    • 面積(幅 × 高さ)を計算して出力する
  3. 以下の処理を行う modifyRectangle という名前の関数を記述します:
    • Rectangle 構造体をパラメータとして受け取る(値渡し)
    • 長方形の幅と高さの両方を2倍にする
    • 色を "Modified" に変更する
    • Inside modifyRectangle function: と出力する
    • displayRectangle を呼び出して、変更された長方形を表示する
  4. main関数内で以下の処理を行います:
    • rect という名前の Rectangle 変数を作成する
    • 入力から幅、高さ、色を読み取り、構造体のメンバに代入する
    • Original rectangle: と出力する
    • displayRectangle を呼び出して、元の長方形を表示する
    • その長方形を引数にして modifyRectangle を呼び出す
    • After modifyRectangle call: と出力する
    • 再度 displayRectangle を呼び出して、元の長方形が変更されていないことを示す

このチャレンジは、構造体の値渡しに関する重要な概念を示しています。構造体を入数に渡すと、関数は構造体の完全なコピーを受け取ります。関数内で行われた変更は、そのコピーにのみ影響し、呼び出し元の関数の元の構造体には影響しません。

チートシート

構造体を関数に渡す際、C言語は値渡し(pass-by-value)を使用します。これは、関数が構造体の完全なコピーを受け取ることを意味します。

構造体のパラメータを受け取るための関数の構文は以下の通りです:

void functionName(struct StructureName parameterName) {
    // 関数の本体
}

Point構造体を使用した例:

void printPoint(struct Point p) {
    printf("Point coordinates: (%d, %d)\n", p.x, p.y);
}

重要な概念:関数内で行われた構造体への変更は、呼び出し元の関数の元の構造体には影響を与えません。これは、関数がデータの独自のコピーを操作するためです。

このアプローチは、元のデータを変更するリスクなしに構造体データを読み取ったり表示したりするのに便利ですが、大きな構造体をコピーすると非効率になる可能性があります。

自分で試してみよう

#include <stdio.h>
#include <string.h>

// TODO: ここで Rectangle 構造体を定義します

// TODO: ここで displayRectangle 関数を記述します

// TODO: ここで modifyRectangle 関数を記述します

int main() {
    // 入力を読み込む
    int width, height;
    char color[15];
    
    scanf("%d", &width);
    scanf("%d", &height);
    scanf("%s", color);
    
    // TODO: Rectangle 変数を作成し、入力値を代入します
    
    // TODO: "Original rectangle:" と出力し、displayRectangle を呼び出します
    
    // TODO: modifyRectangle を呼び出します
    
    // TODO: "After modifyRectangle call:" と出力し、再度 displayRectangle を呼び出します
    
    return 0;
}
quiz icon腕試し

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

Logic & Flowのすべてのレッスン