Is there any way to create generic data structure in C and use functions in accordance with the stored data type, a structure that has various types of data and for example can be printed according to the stored data.
For example,
Suppose I wish to make a binary search tree that has just float's, int's stored. The natural approach to do would be to create an enumeration with int's and float's. it would look something like this:
Typedef enum {INT, FLOAT} DataType;
Typedef struct node
{
void *data;
DataType t;
struct node *left,
*right;
}Node;
if i want print it out:
void printTree(Node *n)
{
if (n != NULL)
{
if (n->t == INT)
{
int *a = (int *) n->data;
printf("%d ", *a);
}
else
{
float *a = (float *) n->data;
printf("%f ", *a);
}
printTree(n->left);
printTree(n->right);
}
}
That's ok but i want to store another data type as a stack, query or something else. So that's why I created a tree that does not depends on a specific data type, such as:
Typedef struct node
{
void *data;
struct node *left,
*right;
}Node;
If i want to print it out i use callback functions, such as:
Node *printTree(Node *n, void (*print)(const void *))
{
if (n != NULL)
{
print(n->data);
printTree(a->left);
printTree(a->right);
}
}
But it falls down when i try to insert a integer and a float and print it out. My question is, Is there a way of creating a generic data structure that a routine depends on a specific data type in one situation but another situation it doesn't , for mixed data type? In this situation i should create a structure that stores int's and float's stores it and use a print function like in the first print code for that in the callback function?
observation: I just declared a node in the structure and did everything on it trying to simplify, but the idea is to use the structure with .h and .c and all this abstraction involving data structures.
I would suggest trying something like the following. You'll noticed that Node
contains a tagged union that allows for either a pointer type, an integer, or a floating point number. When Node
is a pointer type, the custom print
function is called, and in the other cases, the appropriate printf
format is used.
typedef enum {POINTER, INT, FLOAT} DataType;
typedef struct node
{
DataType t;
union {
void *pointer;
int integer;
float floating;
} data;
struct node *left,
*right;
} Node;
void printTree(Node *n, void (*print)(const void *))
{
if (n != NULL) {
switch (n->t) {
case POINTER:
print(n->data.pointer);
break;
case INT:
printf("%d ", n->data.integer);
break;
case FLOAT:
printf("%f ", n->data.floating);
break;
}
printTree(a->left, print);
printTree(a->right, print);
}
}