union {
int i;
char c;
} u;
u.c 是对应在第一个byte还是最后一个byte? 这个是undefined么?
我所知道的就是 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;
}
结构体(
struct
)简单来说,结构体的数据成员在内存中的顺序是确定的,但是每个数据成员前后有可能插入一定数量的位(bit)来保证内存是对齐的。如下图所示:
每个方格右上角的数字即变量的起始地址偏移量。
From C99 §6.7.2.1:
联合体(
union
)简单来说,联合体中的所有成员的地址都是相同的。如下图所示:
三个变量的起始地址偏移量都是 0。
From the C99 standard §6.7.2.1:
参考
C struct memory layout - Stack Overflow
Memory layout of union of different sized member - Stack Overflow
ELF ABI §3.1