联合体的内存问题

union {
    int i;
    char c;
} u;

u.c 是对应在第一个byte还是最后一个byte? 这个是undefined么?

阅读 4.9k
6 个回答

结构体(struct

简单来说,结构体的数据成员在内存中的顺序是确定的,但是每个数据成员前后有可能插入一定数量的位(bit)来保证内存是对齐的。如下图所示:

clipboard.png

每个方格右上角的数字即变量的起始地址偏移量。

From C99 §6.7.2.1:

12 Each non-bit-field member of a structure or union object is aligned in an implementation- defined manner appropriate to its type.

13 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

联合体(union

简单来说,联合体中的所有成员的地址都是相同的。如下图所示:

clipboard.png

三个变量的起始地址偏移量都是 0。

From the C99 standard §6.7.2.1:

14 The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.

参考

对应最低字节。
Image

我所知道的就是 i 和 c 是有相同的地址,这个在标准文档里面有讲到(n1570 6.7.2.1-16小节)
然后找资料的时候有这么两句话,

  • C语言的数据结构都是从低地址向高地址扩展的

  • union的数据成员总是从低地址开始存放

至于对于第几个byte, u.c 和 ((char*)(&u))[0],肯定是同一个byte,那么就是对应第一个byte咯。。

有个问题想请教您!!!!!!!!!
您在2014年01月02日回答
(这个就是传说中的 二进制文件 了.

文件大略 分为 文本的 和二进制的. 其实底下来说, 都是存的 字节码. 但是文本文件里的内容是符合某种编码的. 比如你在文本编辑器里, 用utf8打开, 看到里面没有乱码, 全是有意义的符号, 表示很开心.

但有很多文件, 不是用来在text editor/viewer里显示或者编辑的. 比如一副图片. 再或者我自定义了一种文件格式, 规定前2个字节是0, 后面放utf8 string.)

那该如何让其正常显示呢????

u.c 是对应在第一个byte还是最后一个byte?

首先CPU有大端与小端两类:
大端即对数据的存储由高地址往第地址存储。
如 int a = 0x12345678;存储结构如下:
地址 数据
0 - 0x12
1 - 0x34
2 - 0x56
3 - 0x78

小端即对数据的存储由地地往高地址存储。
如 int a = 0x12345678;存储结构如下:
地址 数据
0 - 0x78
1 - 0x56
2 - 0x34
3 - 0x12

对于共用体的存储方式,还是要看CPU的类型
union {

int i;
char c;

} elem ;

当CPU为小端的时候,char c的值存放在低地址。
当CPU为大端的时候,char c的值存放在高地址。

可以通过下面的函数判断CPU类型,也可以知道实际机器存储union数据类型的方式啦:
typedef enum __bool {false = 0,true =1}bool;

bool is_little_Endian(elem a)
{

a.i = 1;

return a.c == 1 ? true:false;

}

先看是大小端,再看是多少位的操作系统,单字节还是双字节,这些对结果都不一样的。。。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进