如何解决union vs void*,哪个更好?
刚开始学习union的时候还不是很明显,但是在学习了C++ runtime polymorphism之后,我有了一个想法。为什么我使用 union
而不是 void*
?我为两者创建了一个简短的代码示例。
以下是 union
示例:
#include <stdio.h>
#include <stdlib.h>
const int N = 10;
union int_double_t
{
int i;
double d;
};
enum int_double_label
{
INT,DOUBLE
};
struct labeled_int_double_t
{
enum int_double_label label;
union int_double_t value;
};
int main()
{
struct labeled_int_double_t u[N];
for (int i = 0; i < N; ++i)
{
if (rand() % 2)
{
u[i].label = INT;
u[i].value.i = i;
printf("array[%i]: %s\t%i\n",i,u[i].label ? "double" : "int",u[i].value.i);
}
else
{
u[i].label = DOUBLE;
u[i].value.d = i + .1;
printf("array[%i]: %s\t%f\n",u[i].value.d);
}
}
}
以下是 void*
示例:
#include <stdio.h>
#include <stdlib.h>
const int N = 10;
enum int_double_label
{
INT,DOUBLE
};
struct labeled_int_double_t
{
enum int_double_label label;
void* value;
};
int main()
{
struct labeled_int_double_t u[N];
for (int i = 0; i < N; ++i)
{
if (rand() % 2)
{
u[i].label = INT;
u[i].value = malloc(sizeof(int));
*(int*)u[i].value = i;
printf("array[%i]: %s\t%i\n",*(int*)u[i].value);
free(u[i].value);
}
else
{
u[i].label = DOUBLE;
u[i].value = malloc(sizeof(double));
*(double*)u[i].value = i + .1;
printf("array[%i]: %s\t%f\n",*(double*)u[i].value);
free(u[i].value);
}
}
}
两者都使用:gcc -W -Wall -Wextra -pedantic -std=c99
编译,都按预期运行。
输出如下:
array[0]: int 0
array[1]: int 1
array[2]: double 2.100000
array[3]: double 3.100000
array[4]: int 4
array[5]: double 5.100000
array[6]: double 6.100000
array[7]: double 7.100000
array[8]: double 8.100000
array[9]: double 9.100000
我有点看出区别了。使用 union
,我只能使用堆栈内存,但还有其他根本区别吗?
解决方法
虽然你知道自己在做什么,并且仍然知道自己做了什么,但并没有太大区别。
但除此之外(代码是由同事编写的,或者在您刚刚在海滩度假三周之前由您编写),您会为任何强制的清晰度和编译器可以为您检测到错误的任何小事情感到高兴。
对于不断处理相关代码的单个程序员来说,这似乎无关紧要,但对于旧的、大型的或多位置的项目,我觉得“*void
不走运”。如此之多以至于我需要一些时间来意识到在写这篇文章之前这不是一般规则。 ;-)
哪个更好取决于更高级别的上下文使用。未显示的内容。
在特定情况下,每种方法都更胜一筹。
union
优点:简单。
优点:没有分配错误。
优点:只需要简单的副本。
优点:union
的尺寸信息部分。
---:所有对象的大小相同。
缺点:当可能的对象类型在大小上很大时很浪费。
malloc
Pro:每个正确的对象大小。
缺点:每个对象都有指针开销。
缺点:分配可能会失败。
缺点:仅复制指针。需要更多代码来复制引用的对象。
缺点:小对象分配破坏内存。
缺点:需要同伴 free()
。
--
对于 int i,double d
,我更可能使用 union
方法。
旁白:进步的反面是什么?
国会
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。