Menu
Coddy logo textTech

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

Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 53 из 61.

challenge icon

Задание

Легко

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

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

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

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

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

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

Важно: Чтобы отслеживать типы для вывода, вы можете использовать простой параллельный массив индикаторов типов в 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;
}

Все уроки раздела Object Oriented Programming