我想创建一个链表,但我希望数据字段为int或float。我写了一些如下代码:
union int_or_float
{
int int_member;
float float_member;
};
struct node
{
union int_or_float data;
struct node *next;
};
我想写点:
typedef struct node item;
但如何指定哪个类型在联合中我喜欢的项目是什么?
答案 0 :(得分:3)
你没有。工会的根本之处在于它可以是你投入的任何数据。
如果你写信给int_member
,那么它将持有一个int。
如果你写信给float_member
,它会持有一个浮点数。 (如果你随后从int_member
读到了所有地狱,那么它就会崩溃。)
答案 1 :(得分:2)
您无需“指定”任何内容。您只需将值存储在union的相应成员中。
但是,您的结构似乎可以作为某些列表中的节点。如果您的列表旨在同时包含不同类型的值,那么您当然需要某种方法来确定列表中每个元素当前包含的类型。这只能手动完成。即您有责任以某种方式将该信息存储在每个列表项中。例如,您可以在结构中添加type
字段
struct node
{
enum { INT, FLOAT } type;
union int_or_float data;
struct node *next;
};
...
struct node *p;
p = malloc(sizeof *p);
p->type = INT;
p->data.i = 42;
/* ... and add it to the list */
p = malloc(sizeof *p);
p->type = FLOAT;
p->data.f = 3.14;
/* ... and add it to the list */
答案 2 :(得分:1)
当您添加额外的存储空间和条件以检查联合是否存储int
或float
时,您可能只是将字段更改为double
然后您可以轻松适应任何适合int
或float
的值,而不必担心它是哪种类型(在int
为32位且double
为的大多数实现中IEEE 754双精度)。我认为这将是一个更清洁的设计...
答案 3 :(得分:0)
你想要这样的东西:
#include <stdio.h>
union int_or_float
{
int int_member;
float float_member;
};
struct node
{
union int_or_float data;
struct node *next;
};
int main()
{
typedef struct node item;
item one;
one.data.int_member = 10;
item two;
two.data.float_member = 10.f;
printf("%d", one.data.int_member);
printf("%f", two.data.float_member);
return 0;
}
答案 4 :(得分:0)
访问数据时会自动完成。联盟只不过是一种投射指针的方式。
#include <stdio.h>
union number {
int i;
float f;
};
struct node {
union number data;
struct node *next;
};
typedef struct node item;
int main(void) {
item myItem;
myItem.data.i = 12; /* Now contains an int */
myItem.data.f = 12.0; /* Now contains a float */
printf("location of myItem.data is %p\n", &myItem.data);
printf("location of myItem.data.f is %p\n", &myItem.data.f);
printf("myItem.data is %f\n", *(float *)(&myItem.data));
printf("myItem.data.f is %f\n", myItem.data.f);
printf("sizeof(myItem.data) is %lu\n", sizeof(*(float *)(&myItem.data)));
printf("sizeof(myItem.data.f) is %lu\n", sizeof(myItem.data.f));
return 0;
}
这将输出
location of myItem.data is 0x7fff5fbff9f0
location of myItem.data.f is 0x7fff5fbff9f0
myItem.data is 12.000000
myItem.data.f is 12.000000
sizeof(myItem.data) is 4
sizeof(myItem.data.f) is 4
在具有gcc版本4.2.1的Intel Mac上运行/测试(Apple Inc. build 5659)
答案 5 :(得分:0)
您可以在结构中添加一个字段,指示哪个联合成员当前有效。一个简单的例子:
union int_or_float
{
int int_member;
float float_member;
};
struct node
{
union int_or_float data;
bool int_is_valid;
struct node *next;
};
(假设您有#include <stdbool.h>
。)
请注意,完全取决于您保持int_is_valid
成员的值与您存储的最后一个值一致,并仅在int_member
为真时检索int_is_valid
并检索仅当float_member
为假时才int_is_valid
。
在实践中,使用enum
而不是bool
会更清楚。
答案 6 :(得分:-1)
你可能最好同时存储一个float和一个int,然后使用赋值函数将两者都设置为正确的值。一个类可能更适合这个
struct node
{
int idata;
float fdata;
struct node *next;
void setData(int data);
void setData(float data);
};
node::setData(int data)
{
idata = data;
fdata = (float)data;
}
node::setData(float data)
{
idata = (int)data;
fdata = data;
}