Полиморфизм реализации абстрактного типа данных на основе динамического массива - 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\Atd.c:main.c:Помогите мне кто-нибудь, плиз
#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#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 */ }
#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); } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д