C语言结构体与位段

来源:互联网 发布:android登陆界面源码 编辑:程序博客网 时间:2024/06/07 19:09

深度理解结构体与位段

1.结构体的定义 

有以下3种方法定义结构体类型变量。
(1)先声明结构体类型再定义变量

(2)在声明类型的同时定义变量

例如:

struct Student{int num;char name[20];int age;float score;char address;}student1,student2;

(3)直接定义结构体类型变量
struct {    成员表}变量名表;

2.结构体初始化

例如:

struct Student{int num;char name[20];int age;float score;char address[30];}student1={10001,"zhangsan",18,98.9,"太白路五路口"};
3.结构体的typedef 

typedef struct Student{int num;char name[20];int age;float score;char address[30];}Student;
typedef为这个新的结构起了一个名字,叫Node

4.结构体的内存存储(内存对齐规则,为什么存在内存对齐?) 

内存对其规则:

(1)结构的第一个成员永远放在0偏移处;

(2)从第二个成员开始都要对齐到某个对齐数的整数倍处

其中,对齐数为结构成员自身大小和默认对齐数的较小值,默认对齐数:vs---8,  linux---4

(3)结构体自身的总大小必须是最大对齐数的整数倍。

对齐原因:

(1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

(2)性能原因:数据结构(尤其是栈)应尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问,然后拼凑出数据,而对齐的内存访问一次,就可以得到数据。

一个空结构体的大小为1,不是0的原因是:当你定义多个结构体变量时,由于占0个字节,所有他们的起始地址很可能相同,这是不允许出现的,为了避免浪费所以空结构体的大小为一个字节相对合适。

5.位段

(1)一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。

struct S{int a : 2;int b : 10;int c : 5;int d : 20;};int main(){struct S stu;printf("%d\n", sizeof(stu));system("pause:");return 0;}
(2)由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度
(3)位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。

(4)位段的存储和位段的总大小跟平台有关系,位段不存在内存对齐。

(5)位段是不跨平台的,是由于存储方式导致。




原创粉丝点击