Повторение: обобщенный массив
Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 53 из 61.
Задание
ЛегкоДавайте создадим контейнер GenericArray: гибкую структуру данных, которая может хранить смесь целых чисел и строк в одной коллекции с использованием указателей void*.
Вы организуете код в трёх файлах:
generic_array.h: определите структуруGenericArrayс тремя членами: массивvoid**для хранения указателей,intдля текущего количества элементов иintдля вместимости. Объявите прототипы function для создания array, добавления элементов, получения элементов по индексу и освобождения array.generic_array.c: реализуйте функциональность вашего контейнера:create_array: выделяет GenericArray с заданной начальной вместимостью и устанавливает count в 0add_element: сохраняет указательvoid*в следующей доступной позиции и увеличивает count (считайте, что вместимость достаточна)get_element: возвращаетvoid*по указанному индексуfree_array: освобождает массив items и саму структуру GenericArray
main.c: продемонстрируйте работу вашего generic array, сохраняя целые числа и строки. Сначала прочитайте количество добавляемых элементов, затем для каждого элемента прочитайте индикатор типа (iдля integer,sдля строки), за которым следует значение. После добавления всех элементов пройдите по array и выведите каждое значение. Для integer выведите число напрямую. Для строк выведите текст напрямую.
Ваша программа получит:
- Количество добавляемых элементов
- Для каждого элемента: индикатор типа (
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;
}
Все уроки раздела Объектно-ориентированное программирование
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик7Указатели на функции
Объявление указателей на функцииВызов указателей на функцииTypedef для указателей на функцииПередача функций в качестве аргументовИтоги: Диспетчеризация калькулятора10Обобщенные контейнеры
Повторение: указатели voidОбобщенная оберткаОбобщенный обмен (Swap)Обобщенное сравнениеПовторение: обобщенный массив2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигурПотренируйтесь самостоятельно: Онлайн-компилятор C