Menu
Coddy logo textTech

Повторение: обобщенный массив

Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 53 из 61.

challenge icon

Задание

Легко

Давайте создадим контейнер GenericArray: гибкую структуру данных, которая может хранить смесь целых чисел и строк в одной коллекции с использованием указателей void*.

Вы организуете код в трёх файлах:

  • generic_array.h: определите структуру GenericArray с тремя членами: массив void** для хранения указателей, int для текущего количества элементов и int для вместимости. Объявите прототипы function для создания array, добавления элементов, получения элементов по индексу и освобождения array.
  • generic_array.c: реализуйте функциональность вашего контейнера:
    • create_array: выделяет GenericArray с заданной начальной вместимостью и устанавливает count в 0
    • add_element: сохраняет указатель void* в следующей доступной позиции и увеличивает count (считайте, что вместимость достаточна)
    • get_element: возвращает void* по указанному индексу
    • free_array: освобождает массив items и саму структуру GenericArray
  • main.c: продемонстрируйте работу вашего generic array, сохраняя целые числа и строки. Сначала прочитайте количество добавляемых элементов, затем для каждого элемента прочитайте индикатор типа (i для integer, s для строки), за которым следует значение. После добавления всех элементов пройдите по array и выведите каждое значение. Для integer выведите число напрямую. Для строк выведите текст напрямую.

Ваша программа получит:

  1. Количество добавляемых элементов
  2. Для каждого элемента: индикатор типа (i или s), за которым следует значение

При добавлении integer выделите память для int и сохраните указатель. При добавлении строк выделите память и скопируйте строку. При получении выполните обратное приведение к соответствующему типу для вывода.

Важно: Чтобы отслеживать типы при выводе, можно использовать простой параллельный array индикаторов типов в main или сохранять символ индикатора типа рядом с каждым элементом.

Пример вывода, если входные данные — 3, затем i 42, s Hello, i 100:

42
Hello
100

Пример вывода, если входные данные — 4, затем s World, s Generic, i -5, s Arrays:

World
Generic
-5
Arrays

Не забудьте использовать include guards в файле заголовка. Самому контейнеру не нужно знать, какие типы он хранит. Он просто содержит указатели void*. Ответственность за знание типа лежит на коде, который добавляет и получает элементы.

Попробуйте сами

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "generic_array.h"

int main() {
    int n;
    scanf("%d", &n);
    
    // TODO: Создайте GenericArray с ёмкостью n
    
    // TODO: Создайте параллельный массив для отслеживания типов (массив char размера n)
    
    // TODO: Для каждого элемента:
    // - Считайте индикатор типа (i или s)
    // - Считайте значение
    // - Если целое число: выделите память для int, сохраните значение, добавьте в массив
    // - Если строка: выделите память для строки, скопируйте значение, добавьте в массив
    // - Сохраните индикатор типа в вашем параллельном массиве
    
    // TODO: Пройдите по массиву и выведите каждый элемент
    // - Проверьте тип из вашего параллельного массива
    // - Приведите void* обратно к соответствующему типу и выведите
    
    // TODO: Освободите всю выделенную память (целые числа, строки и массив)
    
    return 0;
}

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор C