Menu
Coddy logo textTech

Kontener kształtów

Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 48 z 61.

challenge icon

Wyzwanie

Łatwy

Doprowadźmy projekt Shape Drawer do wielkiego finału! Utworzysz kontener kształtów, który przechowuje mieszaną kolekcję kół i prostokątów, a następnie przejdziesz przez nie, aby obliczyć łączne pole: demonstrując prawdziwą moc polimorfizmu.

Opierając się na wszystkim, co udało Ci się do tej pory stworzyć, Twój kompletny projekt będzie zawierać:

  • shape.h i shape.c: bazowy interfejs Shape oraz funkcję process_shape.
  • circle.h i circle.c: implementację Circle wraz z konstruktorem i obliczaniem pola.
  • rectangle.h i rectangle.c: implementację Rectangle wraz z konstruktorem i obliczaniem pola.
  • main.c: To tutaj dzieje się magia. Utworzysz tablicę wskaźników Shape*, która może przechowywać kształty dowolnego typu. Wypełnij ją mieszanką kół i prostokątów, a następnie użyj pętli, aby obliczyć i wyświetlić łączne pole wszystkich kształtów.

Twój program otrzyma następujące dane wejściowe:

  1. Liczbę kształtów do utworzenia
  2. Dla każdego kształtu: oznaczenie typu (c dla koła, r dla prostokąta), a następnie jego wymiary

Dla każdego kształtu w kontenerze samodzielnie wywołaj draw i area za pośrednictwem wskaźnika Shape* (shapes[i]->draw(shapes[i]), shapes[i]->area(shapes[i])) i dodaj pole do bieżącej sumy. Nie używaj tutaj process_shape z shape.c: ta funkcja wypisuje dodatkowy wiersz Area: dla każdego kształtu, którego nie ma w oczekiwanym wyniku. Po przetworzeniu wszystkich kształtów wypisz łączne pole z dokładnością do 2 miejsc po przecinku, w formacie Total Area: X.XX.

Przykład z danymi wejściowymi 3, a następnie c 5.0, r 4.0 3.0, c 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

Przykład z danymi wejściowymi 2, a następnie r 6.0 4.0, r 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

Najważniejsze jest to, że Twoja tablica przechowuje wskaźniki Shape*. Nie ma znaczenia, czy każdy element jest w rzeczywistości kołem, czy prostokątem. Gdy przechodzisz przez tablicę i wywołujesz draw oraz area za pośrednictwem każdego wskaźnika, automatycznie wykonywana jest właściwa implementacja, zależnie od sposobu utworzenia danego kształtu. To właśnie polimorfizm w praktyce: jedna pętla, jeden interfejs, wiele zachowań.

Pamiętaj, że w tablicy musisz przechowywać wskaźniki do osadzonych elementów Shape konkretnych kształtów. Do obliczania pola koła użyj wartości 3.14159 dla π.

Ważne: odczytywanie znaku typu kształtu: Po odczytaniu liczby kształtów za pomocą scanf("%d", &n) każde kolejne wywołanie odczytujące znak typu musi pomijać znak nowej linii pozostawiony w buforze wejściowym. Aby to zrobić, użyj spacji na początku ciągu formatującego:

scanf(" %c", &type);  // note the space before %c

Bez spacji na początku scanf odczyta znak nowej linii pozostawiony po poprzednim wejściu zamiast oczekiwanego c lub r, przez co sprawdzenie typu kształtu po cichu się nie powiedzie i nie zostanie wygenerowane żadne wyjście.

Spróbuj swoich sił

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

int main() {
    // TODO: Wczytaj liczbę figur
    // TODO: Przydziel pamięć na tablice okręgów, prostokątów i wskaźników Shape*
    // TODO: Przejdź przez każdą figurę, wczytaj jej typ i wymiary,
    //       utwórz figurę i zapisz wskaźnik do jej obiektu bazowego w tablicy shapes
    // TODO: Przejdź przez tablicę shapes, wywołaj shapes[i]->draw(...) oraz
    //       bezpośrednio shapes[i]->area(...) i zsumuj pola figur
    //       (nie wywołuj process_shape: wypisuje dodatkowy wiersz Area)
    // TODO: Wypisz sumę pól figur w formacie: Total Area: X.XX
    // TODO: Zwolnij przydzieloną pamięć
    return 0;
}

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C online