Полиморфизм реализации абстрактного типа данных на основе динамического массива - C (СИ)

Узнай цену своей работы

Формулировка задачи:

ТЗ 1. Необходимо реализовать абстрактный тип данных на основе динамического массива. 2. Программа должна быть написана на языке С. Нельзя использовать возможности языка С++. Это значит, что нельзя использовать cout и cin, вместо них нужно использовать printf() и scanf(). Нельзя использовать using namespace std. Нельзя использовать class, вместо них нужно использовать struct. 3. Абстрактный тип данных должен быть полиморфным. Необходимо задать структуру данных и интерфейс так, чтобы можно было не меняя их работать с данными любого типа внутри структуры. В языке С это делается путём сохранения размера типа данных внутри структуры в отдельной переменной. 4. Функции интерфейса должны быть полиморфны, т.е. принимать аргументы также произвольного типа. Это делается при помощи указателей void*. 5. Собственно, основа вашего задания – это именно реализовать абстрактный тип данных и уметь организовать работу с ним. Ваш «Динамический массив» должен быть полиморфным, и, в общем случае, уметь сохранить и извлечь произвольный тип, а не только те, что заданы вариантом. 6. Интерфейс вашего абстрактного типа данных «Динамический массив» реализован верно, если обращения к полям через « . » или « –> » используются только в функциях интерфейса и нигде вне их. 7. Не разыменовывать указатель void* и не использовать с ним адресную арифметику, например void* ptr = malloc(10); int a = ptr[4]; или char c = *(ptr + 4); Если вы хотите работать с void* как с указателем на байт, то приводите его к типу char*. У типа void же размера нет, поэтому разыменование такого типа, который даже не является типом, бессмысленно. Если ваша среда программирования поддерживает такой подход, то это не значит, что будет поддерживать другая. И использование такого подхода будет считаться примером плохого стиля. Задача моего варианта Тип коллекции - Строка Типы хранимых элементов - Символы Операции - Конкатенация, получение подстроки (с i-го символа по j-й), поиск подстроки (реализовать два варианта: чувствительное к регистру сравнение, и нечувствительное) По ТЗ сделала все пункты Решила проверить полиморфизм для типов хранимых элементов int, float, double Для типа элементов char и int всё работает, а для float и double нет и не могу понять что и где не так, перепробовала кучу вариантов и не получается Вот что в итоге есть Include\Atd.h:
#include 
 
#pragma once
#ifndef Atd_H
#define Atd_H
 
typedef struct Atd_t
 {
    void * ptrArray; /* Указатель на массив */
    unsigned ArraySize; /* Размерность массива*/
    unsigned ElementSize; /* Размерность элемента массива*/
    unsigned AtdType; /* Тип данных: 1 - string, 2 - int, 3 - float, 4 - double, ...*/
 } Atd_t;
 
unsigned LenStr (char * Str);
 
Atd_t * AtdAllocate(unsigned N, unsigned ElementSize, unsigned AtdType);
 
void AtdFree(Atd_t * Atd);
 
void AtdInit(Atd_t * Atd, void * ud_t);
 
void AtdPrint(Atd_t * Atd, char * cDelimiter);
 
unsigned GetAtdSizeArray(Atd_t * Atd);
 
unsigned GetAtdElementSize(Atd_t * Atd);
 
unsigned GetAtdType(Atd_t * Atd);
 
int GetAtdElements(Atd_t * AtdSrc, Atd_t * AtdElements, unsigned BegIndex, unsigned EndIndex);
 
int AtdConcatenation(Atd_t * AtdSrc1, Atd_t * AtdSrc2, Atd_t * AtdTrgt);
 
#endif /*Atd_H*/
Include\Atd.c:
#include 
#include 
#include 
#include 
#include "Atd.h"
 
/*Выделение памяти для Atd на N элементов размером Size*/
Atd_t * AtdAllocate(unsigned N, unsigned Size, unsigned AtdType)
{
    Atd_t * Atd;
 
    /* Выделение памяти под структуру Atd_t*/
    Atd = (Atd_t *) malloc(sizeof(Atd_t));
 
    if (N <= 0)
    {
        printf("\nThe incorrect input ArraySize, is created one element Array\n");
        N = 1;
    }
    if (Size <= 0)
    {
        printf("\nThe incorrect input ElementSize, is created element Size = 1\n");
        Size = 1;
    }
 
    Atd->ArraySize = N;
    Atd->ElementSize = Size;
    Atd->AtdType = AtdType;
 
    /* Выделение памяти под элементы массива ptrArray*/
    Atd->ptrArray = malloc(N * Size);
 
    return Atd;
}

/*Освобождение памяти*/
void AtdFree(Atd_t * Atd)
{
    free(Atd->ptrArray);    /* Освобождение памяти для void * */
    free(Atd);              /* Освобождение памяти для структуры Atd * */
}

/*Инициализация Atd_t */
void AtdInit(Atd_t * Atd, void * ud_t)
{
    char * cptrArray = (char *) Atd->ptrArray;
    char * cptrSrc = (char *) ud_t;
    char * cptrTrgt;
    unsigned ArraySize = Atd->ArraySize;
    unsigned ElementSize = Atd->ElementSize;
    unsigned i, j;
 
    /*
    for (i = 0; i < ArraySize * ElementSize; i++)
    {
        cptrArray[i] = cptrSrc[i];
    }
    */
 
    for (i = 0; i < ArraySize; i++)
    {
        cptrTrgt = &cptrArray[i * ElementSize];
        for (j = 0; j < ElementSize; j++)
            cptrTrgt[j] = cptrSrc[i * ElementSize + j];
    }
}

/*Получение размера Atd_t массива */
unsigned GetAtdSizeArray(Atd_t * Atd)
{
    return (Atd->ArraySize);
}

/*Получение размера элемента Atd_t массива */
unsigned GetAtdElementSize(Atd_t * Atd)
{
    return (Atd->ElementSize);
}
 
/*Получение типа элемента Atd_t массива */
unsigned GetAtdType(Atd_t * Atd)
{
    return (Atd->AtdType);
}

/* Вывод на экран элементов АТД*/
void AtdPrint(Atd_t * Atd, char * cDelimiter)
{
    char * cptrArray = (char *) Atd->ptrArray;
    unsigned ArraySize = Atd->ArraySize;
    unsigned ElementSize = Atd->ElementSize;
    unsigned AtdType = Atd->AtdType;
    unsigned i;
    int IntElement;
    float FloatElement;
    double DoubleElement;
 
    if (AtdType > 4)
        printf("Output for this data type Atd will be implemented in the future");
    else
        for (i = 0; i < ArraySize; i++)
        {
            if (AtdType == 1) /*  1 - string */
                printf("%c", cptrArray[i]);
            else if (AtdType == 2) /*  2 - int */
            {
                IntElement = cptrArray[i *  ElementSize];
                printf("%d", IntElement);
            }
            else if (AtdType == 3) /*  3 - float */
            {
                FloatElement = cptrArray[i *  ElementSize];
                printf("%.2f", FloatElement);
            }
            else if (AtdType == 4) /*  4 - double */
            {
                DoubleElement = cptrArray[i *  ElementSize];
                printf("%5.2f", DoubleElement);
            }
 
           printf("%s", cDelimiter);
        }
}

/* Получение элементов массива с i-го по j-й (для строки - это получение подстроки) */
int GetAtdElements(Atd_t * AtdSrc, Atd_t * AtdElements, unsigned BegIndex, unsigned EndIndex)
{
    char * cptrSrc = (char *) AtdSrc->ptrArray;
    char * cptrTrgt = (char *) AtdElements->ptrArray;
    unsigned ArraySize = AtdSrc->ArraySize;
    unsigned ElementSize = AtdSrc->ElementSize;
    unsigned i;
    unsigned n = 0;
 
    if (AtdSrc->AtdType != AtdElements->AtdType)
    {
        printf("\nOperation is possible only for the same AtdType");
        return (-1); /* Fatal Error */
    }
 
    if (BegIndex <= 0 || BegIndex > EndIndex || EndIndex > ArraySize)
    {
        printf("\nInput Not correct Index value i or j - Index i must be > 0 and <= j and j must be <= SizeArray, i.e. value must be from 1 to %d", ArraySize);
        return (1); /* Error */
    }
 
    for (i = (BegIndex - 1) * ElementSize; i < EndIndex * ElementSize; i++)
        cptrTrgt[n++] = cptrSrc[i];
 
    return (0); /* Success */
}
 
/* Конкатенация */
int AtdConcatenation(Atd_t * AtdSrc1, Atd_t * AtdSrc2, Atd_t * AtdTrgt)
{
    char * cptrSrc1 = (char *) AtdSrc1->ptrArray;
    char * cptrSrc2 = (char *) AtdSrc2->ptrArray;
    char * cptrTrgt = (char *) AtdTrgt->ptrArray;
    unsigned ElementSize = AtdSrc1->ElementSize;
    unsigned cElementsAtdSrc1 = AtdSrc1->ArraySize * ElementSize;
    unsigned cElementsAtdSrc2 = AtdSrc2->ArraySize * ElementSize;
    unsigned NewArraySize = AtdTrgt->ArraySize;
    unsigned ArrayConcat = AtdSrc1->ArraySize + AtdSrc2->ArraySize;
    unsigned i;
 
    if (AtdSrc1->AtdType != AtdSrc2->AtdType)
    {
        printf("\nOperation is possible only for the same AtdType");
        return (-1); /* Fatal Error */
    }
 
    if (NewArraySize != ArrayConcat)
    {
        printf("\nIncorrect Size Atd Concatenation - must be = %d, and the total size is specified = %d", ArrayConcat, NewArraySize);
        return (-2); /* Fatal Error */
    }
 
    for (i = 0; i < cElementsAtdSrc1; i++)
        cptrTrgt[i] = cptrSrc1[i];
 
    for (i = 0; i < cElementsAtdSrc2; i++)
        cptrTrgt[cElementsAtdSrc1 + i] = cptrSrc2[i];
 
    return (0); /* Success */
}
main.c:
#include 
#include 
#include 
#include 
#include "Include/Atd.h"
 
int main()
{
    Atd_t * String1, * String2;
    Atd_t * AtdElements, * ConcatAtd;
    Atd_t * Int1, * Int2;
    Atd_t * Float1, * Float2;
 
    int MaxLenStr = 128;
    char * Str = (char *) malloc(sizeof(char) * MaxLenStr);
    unsigned i, j;
    unsigned AtdSizeArray;
    char ChoiceNext;
 
    unsigned SizeIntArray1 = 10;
    unsigned SizeIntArray2 = 10;
    int IntArray1[] = {10,11,21,31,41,51,61,71,81,91};
    int IntArray2[] = {91,81,71,61,51,41,31,21,11,10};
 
    unsigned SizeFloatArray1 = 10;
    unsigned SizeFloatArray2 = 10;
    float FloatArray1[] = {10.0,11.1,21.2,31.3,41.4,51.5,61.6,71.7,81.8,91.9};
    float FloatArray2[] = {91.1,81.2,71.3,61.4,51.5,41.6,31.7,21.8,11.9,10.0};

    /* Проверка полиморфизма для элементов типа int и float */
 
    /* Работа с int */
    printf("\n\n\nCheck polymorphism for elements of type int\n");
    printf("\nInit array type int for Int1:\n");
    for (i = 0; i < SizeIntArray1; i++)
        printf("%d, ", IntArray1[i]);
 
    /* Выделение памяти для Atd_t */
    Int1 = AtdAllocate(SizeIntArray1, sizeof(int), 2);   /* AtdType = 2 - int */
 
    /* Инициализация Atd_t */
    AtdInit(Int1, IntArray1);
 
    /* Вывод на экран после инициализации Int1 */
    printf("\nOutput Elements Atd with Delimiter:\n");
    AtdPrint(Int1, "|");
 
    /* --- Получение элементов Atd Int1 с i-го по j-й элемент*/
    i = 2;
    j = 5;
 
    /* Выделение памяти для Atd_t Array Size = j - i + 1*/
    AtdElements = AtdAllocate(j - i + 1, GetAtdElementSize(Int1), GetAtdType(Int1));
 
    if (GetAtdElements(Int1, AtdElements, i, j) == 0) /* Если получение элементов с i-го по j-й успешно, выводим элементы на экран */
    {
        printf("\n\nOutput Elements from %d to %d with Delimiter:\n", i, j);
        AtdPrint(AtdElements, "|");
    }
 
    AtdFree(AtdElements);
 
    printf("\n\nInit array type int for Int2:\n");
    for (i = 0; i < SizeIntArray2; i++)
        printf("%d, ", IntArray2[i]);
 
    /* Выделение памяти для Atd_t */
    Int2 = AtdAllocate(SizeIntArray2, sizeof(int), 2);   /* AtdType = 2 - int */
 
    /* Инициализация Atd_t */
    AtdInit(Int2, IntArray2);
 
    /* Вывод на экран после инициализации Int2 */
    printf("\nOutput Elements Atd with Delimiter:\n");
    AtdPrint(Int2, "|");
 
    /* Выделение памяти для Сoncatenation Atd_t */
    ConcatAtd = AtdAllocate(GetAtdSizeArray(Int1) + GetAtdSizeArray(Int2), GetAtdElementSize(Int1), GetAtdType(Int1));
 
    if (AtdConcatenation(Int1, Int2, ConcatAtd) == 0) /* Если Конкатенация успешно, выводим итого на экран */
    {
        printf("\n\nOutput Elements after Concatenation with Delimiter:\n");
        AtdPrint(ConcatAtd, "|");
    }
 
    AtdFree(Int2);
    AtdFree(ConcatAtd);
    AtdFree(Int1);

   /* Работа с float */
    printf("\n\n\nCheck polymorphism for elements of type float");
 
    printf("\n\nInit array type float for Float1:\n");
    for (i = 0; i < SizeFloatArray1; i++)
        printf("%5.2f, ", FloatArray1[i]);
 
    /* Выделение памяти для Atd_t */
    Float1 = AtdAllocate(SizeFloatArray1, sizeof(float), 3);   /* AtdType = 3 - float */
 
    /* Инициализация Atd_t */
    AtdInit(Float1, FloatArray1);
 
    /* Вывод на экран после инициализации Float1 */
    printf("\n\nOutput Elements Atd with Delimiter:\n");
    AtdPrint(Float1, "|");
 
    /* --- Получение элементов Atd Float1 с i-го по j-й элемент*/
    i = 2;
    j = 5;
 
    /* Выделение памяти для Atd_t Array Size = j - i + 1*/
    AtdElements = AtdAllocate(j - i + 1, GetAtdElementSize(Float1), GetAtdType(Float1));
 
    if (GetAtdElements(Float1, AtdElements, i, j) == 0) /* Если получение элементов с i-го по j-й успешно, выводим элементы на экран */
    {
        printf("\n\nOutput Elements from %d to %d with Delimiter:\n", i, j);
        AtdPrint(AtdElements, "|");
    }
 
    AtdFree(AtdElements);
 
    printf("\n\nInit array type float for Float2:\n");
    for (i = 0; i < SizeFloatArray2; i++)
        printf("%5.2f, ", FloatArray2[i]);

    /* Выделение памяти для Atd_t */
    Float2 = AtdAllocate(SizeFloatArray2, sizeof(float), 3);   /* AtdType = 3 - float */
 
    /* Инициализация Atd_t */
    AtdInit(Float2, FloatArray2);
 
    /* Вывод на экран после инициализации Int2 */
    printf("\n\nOutput Elements Atd with Delimiter:\n");
    AtdPrint(Float2, "|");
 
    /* Выделение памяти для Сoncatenation Atd_t */
    ConcatAtd = AtdAllocate(GetAtdSizeArray(Float1) + GetAtdSizeArray(Float2), GetAtdElementSize(Float1), GetAtdType(Float1));
 
    if (AtdConcatenation(Float1, Float2, ConcatAtd) == 0) /* Если Конкатенация успешно, выводим итого на экран */
    {
        printf("\n\nOutput Elements after Concatenation with Delimiter:\n");
        AtdPrint(ConcatAtd, "|");
    }
 
    AtdFree(Float2);
    AtdFree(ConcatAtd);
 
    AtdFree(Float1);

return(0);
 
}
Помогите мне кто-нибудь, плиз

Решение задачи: «Полиморфизм реализации абстрактного типа данных на основе динамического массива»

textual
Листинг программы
/* Вывод на экран элементов АТД*/
void AtdPrint(Atd_t * Atd, char * cDelimiter)
{
    char * cptrArray = (char *) Atd->ptrArray;
    unsigned ArraySize = Atd->ArraySize;
    unsigned ElementSize = Atd->ElementSize;
    unsigned AtdType = Atd->AtdType;
    unsigned i;
    int IntElement;
    float FloatElement;
    double DoubleElement;
 
    if (AtdType > 4)
        printf("Output for this data type Atd will be implemented in the future");
    else
        for (i = 0; i < ArraySize; i++)
        {
            if (AtdType == 1) /* 1 - string */
                printf("%c", cptrArray[i]);
            else if (AtdType == 2) /* 2 - int */
            {
                IntElement = *((int*)&cptrArray[i *  ElementSize]);
                printf("%d", IntElement);
            }
            else if (AtdType == 3) /* 3 - float */
            {
                FloatElement = *((float*)&cptrArray[i *  ElementSize]);
                printf("%.2f", FloatElement);
            }
            else if (AtdType == 4) /* 4 - double */
            {
                DoubleElement = *((double*)&cptrArray[i *  ElementSize]);
                printf("%.2f", DoubleElement);
            }
 
           printf("%s", cDelimiter);
        }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 3.8 из 5
Похожие ответы