Answer the question
In order to leave comments, you need to log in
Working with different data types in C?
Write in C language an implementation of an abstract data type - a "polymorphic" collection based on a dynamic array. The data structure must support working with elements of various types (generally speaking, arbitrary, if they satisfy certain conditions).
- Integers -
Real numbers -
Complex numbers
I can't figure out how to organize work with different types in C
Answer the question
In order to leave comments, you need to log in
You can use the good old way: a structure with two fields: enum and union. Union can be read differently depending on the value of the enumeration.
Well, or void *, instead of union. Or your vtable implementation.
Generally speaking, the set of complex numbers includes real numbers, and those, in turn, include integers. A complex number is a number of the form "a+bi", where a is the real part expressed as a real number, b is the coefficient of the imaginary part expressed as a real number, i = the imaginary unit.
Based on this, you can try to use an array of structures, where each element is a structure that expresses a complex number. For real numbers, the fields b and i will be equal to zero, for integers, when calculating, the fractional part will have to be ignored.
There are many ways to implement a polymorphic collection in C, and each implementation has its pros and cons. The most popular and simplest of them is probably through void*. Although it is suitable for most cases, it still has the disadvantage of inconsistent data layout in memory and type safety. So here are a couple more possible implementations that might suit you better:
By stuffing the entire implementation of an array into a macro, you can declare the necessary, type-safe arrays if necessary.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define ARRAY_DECLARE(type) \
struct array_##type { \
size_t size; \
size_t capacity; \
type* data; \
}; \
\
struct array_##type* array_##type##_create(size_t init_cap) { \
struct array_##type* self = malloc(sizeof(struct array_##type));\
self->capacity = init_cap; \
self->data = calloc(init_cap, sizeof(type)); \
} \
\
void array_##type##_push_back(struct array_##type* self, type value) { \
if (self->size == self->capacity) { \
type* temp = calloc(self->size + 1, sizeof(type)); \
memmove(temp, self->data, self->size * sizeof(type)); \
free(self->data); \
self->data = temp; \
} \
self->data[self->size++] = value; \
}
ARRAY_DECLARE(int);
ARRAY_DECLARE(float);
int main(void) {
struct array_int* iarr = array_int_create(1);
array_int_push_back(iarr, 42);
array_int_push_back(iarr, 1337);
for (int i = 0; i < 2; ++i) {
printf("%d\n", iarr->data[i]);
}
struct array_float* farr = array_float_create(1);
...
return 0;
}
/* Где-то в array.h */
struct array {
size_t size;
size_t capacity;
void* data;
void (*push_back)(struct array* self, void* value);
void* (*get)(struct array* sefl, size_t index);
};
/* Где-то в arra_int.h */
void array_int_push_back(struct array* self, void* value) {
if (self->size == self->capacity) {
int* temp = calloc(self->size + 1, sizeof(int));
memmove(temp, self->data, self->size * sizeof(int));
free(self->data);
self->data = temp;
}
int* int_data = (int*)self->data;
int_data[self->size++] = *(int*)value;
}
void* array_int_get(struct array* self, size_t index) {
return ((int*)self->data) + index;
}
struct array* array_int_create(size_t init_cap) {
struct array* self = malloc(sizeof(struct array));
self->push_back = array_int_push_back;
self->get = array_int_get;
self->capacity = init_cap;
self->data = calloc(init_cap, sizeof(int));
return self;
}
int main(void) {
struct array* arr = array_int_create(1);
int value = 42;
arr->push_back(arr, &value);
value = 1337;
arr->push_back(arr, &value);
for (int i = 0; i < 2; ++i) {
printf("%d\n", *((int*)arr->get(arr, i)));
}
return 0;
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question