C语言 我们可以在联合中使用指针吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4748366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can we use pointer in union?
提问by Chandrakant
If no why? Uses of union over structure??
如果没有为什么?联合在结构上的用途?
回答by paxdiablo
You can use any data type in a union, there's no restriction.
您可以在联合中使用任何数据类型,没有限制。
As to the use of unions over structures, structures lay out their data sequentially in memory. This mean all their sub-components are separate.
至于在结构上使用联合,结构将其数据按顺序排列在内存中。这意味着它们的所有子组件都是独立的。
Unions, on the other hand, use the same memory for all their sub-components so only one can exist at a time.
另一方面,联合对其所有子组件使用相同的内存,因此一次只能存在一个。
For example:
例如:
+-----+-----+
struct { int a; float b } gives | a | b |
+-----+-----+
^ ^
| |
memory location: 150 154
|
V
+-----+
union { int a; float b } gives | a |
| b |
+-----+
Structures are used where an "object" is composed of other objects, like a point object consisting of two integers, those being the x and y coordinates:
在“对象”由其他对象组成的情况下使用结构,例如由两个整数组成的点对象,这些整数是 x 和 y 坐标:
typedef struct {
int x; // x and y are separate
int y;
} tPoint;
Unions are typically used in situation where an object can be one of many things but only one at a time, such as a type-less storage system:
联合通常用于对象可以是许多事物之一但一次只能是一个的情况,例如无类型存储系统:
typedef enum { STR, INT } tType;
typedef struct {
tType typ; // typ is separate.
union {
int ival; // ival and sval occupy same memory.
char *sval;
}
} tVal;
They are useful for saving memory although that tends to be less and less of a concern nowadays (other than in low-level work like embedded systems) so you don't see a lot of it.
它们对于节省内存很有用,尽管现在人们越来越不关心(除了嵌入式系统等低级工作),所以你看不到很多。
回答by paxdiablo
Well, according to ISO/IEC 9899:TC3 (the C99 standard):
好吧,根据 ISO/IEC 9899:TC3(C99 标准):
A union type describes an overlapping nonempty set of member objects, each of which has an optionally specified name and possibly distinct type.
联合类型描述了一组重叠的非空成员对象,每个成员对象都有一个可选的指定名称和可能不同的类型。
In short, the memory space of union members overlaps, and the names you give to union members allow you to read memory at that location in size. Consider:
简而言之,联合成员的内存空间是重叠的,你给联合成员起的名字允许你读取该位置的内存大小。考虑:
#include <stdio.h>
#include <stdint.h>
typedef union
{
struct
{
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
};
uint32_t x;
} somenewtype;
typedef union
{
uint32_t* p;
uint8_t* q;
} somepointer;
int main(int argc, char** argv)
{
uint32_t r;
uint8_t s;
somenewtype z;
somepointer p;
r = 0x11223344; s = 0x11;
z.x = 0x11223344;
p.p = &r;
p.q = &s;
printf("%x%x%x%x\n", z.d, z.c, z.b, z.a);
printf("%x %x\n", *(p.p), *(p.q));
}
In the first printf, what we're doing is printing out 8-bit parts of the 32-bit integer. Hoping of course for no padding in that anonymous struct.
在第一个 printf 中,我们所做的是打印出 32 位整数的 8 位部分。当然希望匿名结构中没有填充。
In the second printf? I had to step through using gdb to understand, but I did:
在第二个printf?我不得不逐步使用 gdb 来理解,但我做到了:
p.p = (uint32_t *) 0x7fffffffde5c;
p.q = (uint8_t *) 0x7fffffffde5b "1D3\"1P77777";
p.p = (uint32_t *) 0x7fffffffde5b;
Well of course, pointers are all the same size, so assigning p.qoverwrites the address of p.p. I suspect strongly that de-referencing the address of the 32-bit integer to an 8-bit pointer is printing "whatever is at that location + 32 bits in size" which co-incidentally for me happens to be 22334411. But I suspect, at that point, the behaviour is undefined.
当然,指针的大小都是一样的,所以赋值会p.q覆盖p.p. 我强烈怀疑将 32 位整数的地址取消引用到 8 位指针会打印“该位置的任何内容 + 32 位大小”,这对我来说恰好是22334411. 但我怀疑,在这一点上,行为是未定义的。
Anyway, the point of that little exercise was to show you that:
不管怎样,那个小练习的目的是向你展示:
- unions can be used to access the same memory location through a different "type" modifier.
- You have to be careful what you do and understand the underlying type you're using. If you're going to use pointers, beware their modification as you might start pointing to who knows what.
- 联合可用于通过不同的“类型”修饰符访问相同的内存位置。
- 你必须小心你所做的并了解你正在使用的底层类型。如果您打算使用指针,请注意它们的修改,因为您可能会开始指向谁知道什么。
I should point out I can see the practical use for somenewtypebut not for somepointer- that was a contrived example I was pretty sure would break.
我应该指出,我可以看到 forsomenewtype但不是 for的实际用途somepointer——这是一个人为的例子,我很确定会失败。

