Powtórzenie: tablica generyczna
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 53 z 61.
Wyzwanie
ŁatwyStwórzmy kontener GenericArray: elastyczną strukturę danych, która może przechowywać w tej samej kolekcji zarówno liczby całkowite, jak i ciągi znaków, używając wskaźników void*.
Rozmieścisz swój kod w trzech plikach:
generic_array.h: Zdefiniuj strukturęGenericArrayz trzema elementami: tablicąvoid**do przechowywania wskaźników, wartościąintokreślającą bieżącą liczbę elementów oraz wartościąintokreślającą pojemność. Zadeklaruj prototypy funkcji tworzącej tablicę, dodającej elementy, pobierającej elementy według indeksu i zwalniającej tablicę.generic_array.c: Zaimplementuj funkcjonalność kontenera:create_array: alokuje GenericArray o podanej pojemności początkowej i ustawia liczbę elementów na 0add_element: zapisuje wskaźnikvoid*w następnym wolnym miejscu i zwiększa liczbę elementów (załóż, że pojemność jest wystarczająca)get_element: zwraca wartośćvoid*z określonego indeksufree_array: zwalnia tablicę elementów oraz samą strukturę GenericArray
main.c: Zademonstruj działanie tablicy generycznej, przechowując w niej zarówno liczby całkowite, jak i ciągi znaków. Wczytaj liczbę elementów do dodania, a następnie dla każdego elementu wczytaj oznaczenie typu (idla liczby całkowitej,sdla ciągu znaków), a po nim wartość. Po dodaniu wszystkich elementów przejdź przez tablicę i wypisz każdą wartość. W przypadku liczb całkowitych wypisz bezpośrednio liczbę. W przypadku ciągów znaków wypisz bezpośrednio tekst.
Program otrzyma:
- Liczbę elementów do dodania
- Dla każdego elementu: oznaczenie typu (
ilubs), a po nim wartość
Podczas dodawania liczb całkowitych alokuj pamięć dla wartości typu int i zapisz wskaźnik. Podczas dodawania ciągów znaków alokuj pamięć i skopiuj ciąg. Podczas pobierania rzutuj wskaźnik z powrotem na odpowiedni typ, aby wypisać wartość.
Ważne: Aby śledzić typy na potrzeby wypisywania, możesz użyć w main prostej równoległej tablicy oznaczeń typów albo przechowywać znak oznaczenia typu razem z każdym elementem.
Przykładowe wyjście dla danych wejściowych 3, następnie i 42, s Hello, i 100:
42
Hello
100Przykładowe wyjście dla danych wejściowych 4, następnie s World, s Generic, i -5, s Arrays:
World
Generic
-5
ArraysPamiętaj o użyciu strażników nagłówka w pliku nagłówkowym. Sam kontener nie musi wiedzieć, jakie typy przechowuje. Przechowuje tylko wskaźniki void*. Za znajomość typu odpowiada kod dodający i pobierający elementy.
Spróbuj swoich sił
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "generic_array.h"
int main() {
int n;
scanf("%d", &n);
// TODO: Utwórz GenericArray o pojemności n
// TODO: Utwórz równoległą tablicę do śledzenia typów (tablicę char o rozmiarze n)
// TODO: Dla każdego elementu:
// - Odczytaj oznaczenie typu (i lub s)
// - Odczytaj wartość
// - Jeśli to liczba całkowita: przydziel pamięć na int, zapisz wartość i dodaj ją do tablicy
// - Jeśli to ciąg znaków: przydziel na niego pamięć, skopiuj wartość i dodaj ją do tablicy
// - Zapisz oznaczenie typu w równoległej tablicy
// TODO: Przejdź przez tablicę i wypisz każdy element
// - Sprawdź typ w równoległej tablicy
// - Rzutuj void* z powrotem na odpowiedni typ i wypisz wartość
// TODO: Zwolnij całą przydzieloną pamięć (na liczby całkowite, ciągi znaków i tablicę)
return 0;
}
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania modularnego
Pliki nagłówkoweZabezpieczenia przed wielokrotnym dołączeniemPliki źródłoweFunkcje statycznePodsumowanie: kalkulator modularny4Enkapsulacja
Koncepcja niejawnych wskaźnikówDefiniowanie niejawnych strukturGettery i setteryWalidacja w setterachPowtórka: tajemnicze pudełko7Wskaźniki do funkcji
Deklarowanie wskaźników do funkcjiWywoływanie funkcji przez wskaźnikiTypedef dla wskaźników do funkcjiPrzekazywanie funkcji jako argumentówPodsumowanie: wybór działania kalkulatora10Kontenery generyczne
Powtórzenie: wskaźniki voidGeneryczny wrapperGeneryczna zamianaGeneryczne porównywaniePowtórzenie: tablica generyczna2Obiekty i metody
Struktury jako obiektyWskaźnik „self”Poprawność constWskaźnik czy wartośćMetody pomocniczePodsumowanie: menedżer punktów5Projekt: Proste konto bankowe
Konfiguracja projektuImplementacja konta8Polimorfizm
Wskaźniki do funkcji w strukturachSymulowanie metodKoncepcja interfejsuImplementowanie interfejsówIteracja polimorficznaPodsumowanie: Greeter11Wzorce projektowe w C
Wzorzec SingletonWzorzec fabrykiWzorzec iteratoraPodsumowanie: fabryka loggera3Cykl życia obiektu
Wzorzec konstruktoraWzorzec destruktoraInicjalizacja na stosieKopia głębokaPodsumowanie: klasa opakowująca ciąg znaków6Dziedziczenie przez kompozycję
Osadzanie strukturZasada pierwszego elementuDostęp do elementów klasy nadrzędnejKonwersja w górę hierarchiiPodsumowanie: hierarchia kształtów9Projekt: Rysownik kształtów
Przegląd projektuImplementacja kołaImplementacja prostokątaZastosowanie polimorfizmuKontener kształtówPoćwicz samodzielnie: Kompilator C online