Menu
Coddy logo textTech

Powtórzenie: tablica generyczna

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

challenge icon

Wyzwanie

Łatwy

Stwó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ę GenericArray z trzema elementami: tablicą void** do przechowywania wskaźników, wartością int określającą bieżącą liczbę elementów oraz wartością int okreś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 0
    • add_element: zapisuje wskaźnik void* 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 indeksu
    • free_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 (i dla liczby całkowitej, s dla 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:

  1. Liczbę elementów do dodania
  2. Dla każdego elementu: oznaczenie typu (i lub s), 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
100

Przykładowe wyjście dla danych wejściowych 4, następnie s World, s Generic, i -5, s Arrays:

World
Generic
-5
Arrays

Pamię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

Poćwicz samodzielnie: Kompilator C online