程序的机器级表示 - 异构的数据结构

用户头像
引花眠
关注
发布于: 2020 年 09 月 13 日

在C语言中有两种将不同类型的数据组合创建的形式: 结构(structure)用struct关键字声明 将多个对象集合到一个单位中 联合(union)用union关键字声明 允许用几种不同的类型引用同一对象



结构

使用struct关键字声明创建一个数据类型,通过名字引用不同的部分。与数组一样,结构的所有部分都是存放在内存中一段连续的区域 指向结构的指针指向结构的第一个字节的地址。



struct rec{
int i;
int j;
int a[2];
int *p;
}



这个结构有四个字段:两个int,一个由两个int组成的数组,和一个8字节的指针,总共24字节。 在编译阶段会对结构的访问进行处理,以偏移量的形式访问,在编译之后的代码中不包括关于字段或字段名称的信息。



联合

union U3{
char c;
int i[2];
double v;
}

struct S3{
char c;
int i[2];
double v;
}



union与struct的语法差别不是很大,但是语义差别很大。 在x86-64Linux机器上,字段偏移量、数据类型、和完整大小如下



类型 c i v 大小
S3 0 4 16 24
U3 0 0 0 8



联合的总大小等于它最大字段的大小 对应指向union U3 * 的指针p, p->c,p->i[0],p->v引用的都是数据结构的起始位置。 联合的一般用法是事先知道一个数据结构中的不同字段是有是互斥的,那么可以使用联合。



数据对其

许多计算机系统中对数据的合法地址作出了限制,要求某种类型对象的地址必须是某个值K的倍数(通常是2、4或8)。 这种对其可以简化形成处理器和内存系统之间的接口的硬件设计,比如可以简化内存数据的读取。 x86-64 Intel建议 基本对其原则



K 类型
1 char
2 short
4 int, float
8 long, double, char*



所以对于包含结构的代码,编译器可能需要在字段分配中插入间隙 对于



struct S1{
int i;
char c;
int j;
}



如果需要满足对其要求,则j的偏移量就必须是8,总大小是12



i c j
0 5 8



但是对于如下的结构



struct S2{
int i;
int j;
char c;
}



i j c
0 4 9



所有元素的偏移量都满足条件,可以只分配9字节。但是编译器分配的是12字节,在c之后还有3字节的填充。 这是因为,考虑如下代码 struct S2 d[4]; 如果每个S2只分配9个字节,则d[1].i的地址就是10,不满足对其要求。



参考资料

  1. 豆瓣-深入理解计算机系统(原书第3版)



发布于: 2020 年 09 月 13 日 阅读数: 18
用户头像

引花眠

关注

还未添加个人签名 2018.06.11 加入

还未添加个人简介

评论

发布
暂无评论
程序的机器级表示-异构的数据结构