Saj*_*ani 3 c c++ python java programming-languages
可能重复:
C中结构和联合之间的差异
我在C中看到了这个代码用于联合:
union time
{
long simpleDate;
double perciseDate;
} mytime;
Run Code Online (Sandbox Code Playgroud)
联合和C中的结构有什么区别?你会在哪里使用工会,它有什么好处?Java,C++和/或Python中是否有类似的构造?
unw*_*ind 14
联合的行为就好像它的所有成员都在内存中的相同位置,重叠.
当您想要表示某种"通用"值或可以是任何一组类型的值时,这非常有用.由于字段重叠,因此只有在您知道之前已初始化字段时,才能合法访问该字段.尽管如此,由于C不会检查这一点,并且许多编译器会发出允许它的代码,因此这是一个常见的技巧...有趣的类型转换,例如:
union {
int integer;
float real;
} convert;
convert.real = 3.14;
printf("The float %f interpreted as an integer is %08x", convert.real, convert.integer);
Run Code Online (Sandbox Code Playgroud)
对于更加完善的用法,您可以跟踪最后存储在union中的内容,它可以查找如下所示:
typedef enum { INTEGER = 0, REAL, BOOLEAN, STRING } ValueType;
typedef struct {
ValueType type;
union {
int integer;
float real;
char boolean;
char *string;
} x;
} Value;
Run Code Online (Sandbox Code Playgroud)
在这里,请注意联合实际上是周围结构中的一个字段Value.访问可能如下所示:
void value_set_integer(Value *value, int x)
{
value->type = INTEGER;
value->x.integer = x;
}
Run Code Online (Sandbox Code Playgroud)
这记录了union的当前内容是一个整数,并存储给定的值.例如打印a的功能Value可以检查type成员,并做正确的事情:
void value_print(const Value *value)
{
switch(value->type)
{
case INTEGER:
printf("%d\n", value->x.integer);
break;
case REAL:
printf("%g\n", value->x.real);
break;
/* ... and so on ... */
}
}
Run Code Online (Sandbox Code Playgroud)
Java中没有等价物.C++几乎是C的超集,具有相同的功能.它甚至"one-ups"C的实施,并允许匿名工会.在C++中,上面的内容可能没有命名内部union(x),这会使代码缩短很多.
Dou*_* T. 11
所以在你的例子中,当我分配时间时:
int main()
{
time t;
}
Run Code Online (Sandbox Code Playgroud)
编译器可以解释&t中的内存,就好像它是一个long:
t.simpleDate;
Run Code Online (Sandbox Code Playgroud)
或者好像是双重的:
t.perciseDate;
Run Code Online (Sandbox Code Playgroud)
所以如果t的内存的原始十六进制看起来像
0x12345678;
Run Code Online (Sandbox Code Playgroud)
该值可以"解析"为double或long,具体取决于其访问方式.因此,为了使它有用,您必须知道如何将long和double打包并准确地在内存中进行格式化.例如,long将是一个2-s补码有符号整数,您可以在这里阅读.你可以在这里学习如何用二进制格式化double .
但是,结构只是将单独的变量分组,将不同的地址间隔分组到一个内存块中.
(注意你的例子可能很危险,因为sizeof(long)可能是32位而sizeof(double)总是64位)
当您需要"原始"表示(如char数组)和"消息"表示时,通常会使用联合.例如,要通过套接字发送的消息:
struct Msg
{
int msgType;
double Val1;
double Val2;
}; // assuming packing on 32-bit boundary
union
{
Msg msg;
unsigned char msgAsBinary[20];
};
Run Code Online (Sandbox Code Playgroud)
希望有所帮助.
| 归档时间: |
|
| 查看次数: |
3700 次 |
| 最近记录: |