Menu
Coddy logo textTech

図形コンテナ

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

challenge icon

チャレンジ

簡単

Shape Drawerプロジェクトをいよいよ完成させましょう!Circle(円)とRectangle(長方形)が混在するコレクションを保持するシェイプコンテナを作成し、それらを反復処理して総面積を計算します。これにより、ポリモーフィズムの真の力を実証します。

これまでに作成したすべてを基に、完成したプロジェクトには以下が含まれます:

  • shape.hshape.c: ベースとなる Shape インターフェースと process_shape 関数。
  • circle.hcircle.c: コンストラクタと面積計算を含む Circle の実装。
  • rectangle.hrectangle.c: コンストラクタと面積計算を含む Rectangle の実装。
  • main.c: ここで魔法が起こります。任意の図形タイプを保持できる Shape* ポインタの配列を作成します。そこに Circle と Rectangle を混在させて格納し、配列をループしてすべての図形を合わせた総面積を計算し、表示します。

プログラムは以下の入力を受け取ります:

  1. 作成する図形の数
  2. 各図形について:タイプ識別子(円の場合は c、長方形の場合は r)と、それに続く寸法

コンテナ内の各図形について、その描画出力をプリントしてください。すべての図形を処理した後、総面積を小数点以下2桁で Total Area: X.XX という形式でプリントしてください。

入力が 3、次に c 5.0r 4.0 3.0c 2.0 の場合の例:

Drawing Circle with radius: 5.00
Drawing Rectangle with width: 4.00 and height: 3.00
Drawing Circle with radius: 2.00
Total Area: 103.11

入力が 2、次に r 6.0 4.0r 3.0 2.0 の場合の例:

Drawing Rectangle with width: 6.00 and height: 4.00
Drawing Rectangle with width: 3.00 and height: 2.00
Total Area: 30.00

重要なポイントは、配列が Shape* ポインタを格納していることです。配列は、各要素が実際には Circle なのか Rectangle なのかを気にしません。各ポインタを介して drawarea を呼び出すと、各図形がどのように構築されたかに基づいて、正しい実装が自動的に実行されます。これがポリモーフィズムの働きです。1つのループ、1つのインターフェースで、複数の振る舞いを実現します。

配列には、具体的な図形構造体の中に埋め込まれた Shape メンバへのポインタを格納する必要があることに注意してください。円の面積計算には π として 3.14159 を使用してください。

重要 — 図形タイプの文字の読み取り: scanf("%d", &n) で図形の数を読み取った後、それに続くタイプ文字を読み取る各呼び出しでは、入力バッファに残っている改行文字をスキップする必要があります。これを行うには、書式指定文字列に先行スペースを使用します:

scanf(" %c", &type);  // %c の前のスペースに注目してください

先行スペースがない場合、scanf は意図した cr ではなく、前の入力から残された改行文字を読み取ってしまい、図形タイプのチェックが静かに失敗して出力が表示されなくなります。

自分で試してみよう

#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"

int main() {
    // TODO: 図形の数を読み込む
    // TODO: 円、長方形、および `Shape*` ポインタ用の配列を割り当てる
    // TODO: 各図形をループ処理し、そのタイプと寸法を読み込む
    //       図形を作成し、そのベースへのポインタを `shapes` 配列に格納する
    // TODO: `shapes` 配列をループ処理し、各図形で `draw` を呼び出す
    //       そして合計面積を累積する
    // TODO: 合計面積を次の形式で出力する: Total Area: X.XX
    // TODO: 割り当てられたメモリを解放する
    return 0;
}

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