问题
I have a project that the teacher asks us to do some operations in a linked list. Okay, they are pretty easy to implement but I'm having trouble to manage the data inside of my list. They can be any of those: int, char, float or string(char array). I know how to link any of those individually but when they're mixed up things start to get messy.
I have not tried much, I'm stuck. Here are some thoughts that passed through my mind: create 4 structs, 1 for each data type (but I've never seen a linked list of different structs, maybe it's not a list by definition because they are not of the same struct type) or create 1 struct with a declaration for every data type. It's important to tell that I have a variable that tells me what type of data I'm managing at that moment (but when I pass the arguments for my function, I don't have all of them, unless I come up with some flags but it seems pretty dumb and the project didn't specify any limitations for my variables).
Sorry for not showing any code, I think that it's not necessary in this case because my ideas are not working. I can show you the results that I expect to have, for example:
Given the data (the first number tells me how many nodes my list has):
5
f 3.14
d 100
c x
s gardenal
d 300
I expect my result to be:
3.1400 100 x gardenal 300
I'm new at this subject and I tried to explicit my ideas of code above. Thank you for reading this far and have a nice Thursday.
回答1:
In general you need to add a type tag to struct Node so that you can track the kind of data stored in the individual nodes.
For storing data you can use a void pointer or you can use a union. If you use a void pointer you'll need casting whenever accessing data. If you use a union every node will end up using memory corresponding to the size of the largest union member.
Here is a simple example using void pointer:
#include <stdio.h>
#include <stdlib.h>
enum ListType
{
INT = 0,
FLOAT,
CHAR,
STRING,
};
struct Node
{
struct Node *next;
enum ListType type;
void *data;
};
void printNode(struct Node *p)
{
switch (p->type)
{
case INT:
printf("%d ", *((int*)p->data));
break;
case FLOAT:
printf("%f ", *((float*)p->data));
break;
case CHAR:
printf("%c ", *((char*)p->data));
break;
case STRING:
printf("%s ", (char*)p->data);
break;
default:
printf("ERROR ");
break;
}
}
void printList(struct Node *p)
{
while(p)
{
printNode(p);
p = p->next;
}
}
void freeListData(struct Node *p)
{
while(p)
{
free(p->data);
p = p->next;
}
}
int main(void) {
// Build the list manually to illustrate the printing
struct Node N1;
struct Node N2;
N1.type = FLOAT;
N1.data = malloc(sizeof(float));
*((float*)N1.data) = 3.14;
N1.next = &N2;
N2.type = INT;
N2.data = malloc(sizeof(int));
*((int*)N2.data) = 100;
N2.next = NULL;
// .. more nodes
printList(&N1);
freeListData(&N1);
return 0;
}
Output:
3.140000 100
And here is an example using union:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum ListType
{
INT = 0,
FLOAT,
CHAR,
STRING,
};
union ListData
{
int d;
float f;
char c;
char *str; // Memory for the string must be malloc'ed
};
struct Node
{
struct Node *next;
enum ListType type;
union ListData data;
};
void printNode(struct Node *p)
{
switch (p->type)
{
case INT:
printf("%d ", p->data.d);
break;
case FLOAT:
printf("%f ", p->data.f);
break;
case CHAR:
printf("%c ", p->data.c);
break;
case STRING:
printf("%s ", p->data.str);
break;
default:
printf("ERROR ");
break;
}
}
void printList(struct Node *p)
{
while(p)
{
printNode(p);
p = p->next;
}
}
void freeListStrings(struct Node *p)
{
while(p)
{
if (p->type == STRING) free(p->data.str);
p = p->next;
}
}
int main(void) {
// Build the list manually to illustrate the printing
struct Node N1;
struct Node N2;
struct Node N3;
N1.type = FLOAT;
N1.data.f = 3.14;
N1.next = &N2;
N2.type = INT;
N2.data.d = 100;
N2.next = &N3;
N3.type = STRING;
N3.data.str = malloc(sizeof "Hello World");
strcpy(N3.data.str, "Hello World");
N3.next = NULL;
// .. more nodes
printList(&N1);
freeListStrings(&N1);
return 0;
}
Output:
3.140000 100 Hello World
来源:https://stackoverflow.com/questions/56058237/how-to-manage-different-kinds-of-data-in-a-linked-list