我有一个项目,老师要求我们在链接列表中进行一些操作。好的,它们很容易实现,但是我无法管理列表中的数据。它们可以是以下任意一种:int,char,float或string(char数组)。我知道如何单独链接任何一个,但是当它们混合在一起时,事情开始变得混乱。
我没有尝试太多,我被卡住了。这是我想到的一些想法:创建4个结构,每种数据类型1个(但我从未见过不同结构的链表,也许不是定义列表,因为它们不是同一结构类型)或为每种数据类型创建一个带有声明的结构。重要的是要告诉我有一个变量,该变量可以告诉我当时正在管理的数据类型(但是,当我为函数传递参数时,我并没有全部参数,除非我想出了一些标志但是看起来很愚蠢,而且该项目没有为我的变量指定任何限制)。
很抱歉没有显示任何代码,我认为在这种情况下没有必要,因为我的想法没有用。我可以向您显示期望的结果,例如:
给出数据(第一个数字告诉我列表中有多少个节点):
5
f 3.14
d 100
c x
园林
d 300
我希望我的结果是:
3.1400 100 x园林300
我是这个学科的新手,我试图在上面阐明我的代码思想。感谢您阅读本文并祝您星期四愉快。
答案 0 :(得分:5)
通常,您需要向struct Node
添加一个类型标记,以便可以跟踪存储在各个节点中的数据的种类。
对于存储数据,可以使用空指针,也可以使用联合。如果使用空指针,则在访问数据时都需要进行强制转换。如果使用联合,则每个节点最终将使用与最大联合成员的大小相对应的内存。
这是一个简单的示例,使用空指针:
#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;
}
输出:
3.140000 100
这是使用联合的示例:
#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;
}
输出:
3.140000 100 Hello World