结构体的定义和使用和位段的使用

来源:互联网 发布:马泰尔家族知乎 编辑:程序博客网 时间:2024/05/17 15:19

结构体(struct),也叫结构,是由一系列具有相同类型或不同类型的数据构成的数据集合。

比如:描述一个学生,可能需要描述他的学号,姓名,成绩等。

一. 声明及定义结构体变量

有三种方法定义结构体变量

1. 先声明结构体类型,再定义该类型的变量,例如:


struct student{char name[20];char sex[5];char number[30];double score[50];}a1,a2;

2 声明的同时定义,例如

struct student{char name[20];char sex[5];char number[30];double score[50];}a1,a2;


3.  不指定类型名直接定义结构体类型变量,匿名定义,只能用一次

empty
二.结构体变量的初始化

1直接初始化

struct student{char name[20];char sex[5];char number[30];double score[5];};int main(){struct student  n = { "zhangsan", "nan", "201512030223", {100,100,100,100,100} };return 0;}

2.用typedef定义后用改变后的类型名定义

用typedef将原来的类型名struct student  改为student  在定义


typedef struct student{char name[20];char sex[5];char number[30];double score[5];}student;int main(){ student  n = { "lisi ", "nan", "201512030224", { 60, 60, 60, 60, 60 } };return 0;}

三. 结构体在内存中的储存


typedef struct student{char name[20];char sex[5];char number[30];double score[5];}student;int main(){printf("%d\n",sizeof(student));system("pause");return 0;}

这个程序运行的结果是96

为什么那?

内存对齐的3条规则(要牢记):

1、结构的第一个成员永远都放在结构的0偏移处。

      偏移就是往后挪,n偏移就是从系统默认开始分配内存的地方往后挪n个字节,0偏移就是挪0个,也就是相当于没有挪。

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

      对齐数:结构体成员自身大小和默认对齐数的较小值。

      默认对齐数:VS-----8  linux-----4

3、结构体的总大小必须是最大对齐数的整数倍。

4.  如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是最大对齐数(含嵌套结构体的对齐数)的整数倍。

例如:

#define _CRT_SECURE_NO_WARNINGS 1#includetypedef struct student{char name[20];//0-19char sex[5];//20-24char number[30];//25-54double score[5];//56-95}student;//总大小为96struct student1{student a;//0-95char b;//96};//总大小为97,但是必须为最大步数(double)的整数倍//所以大小为104int main(){printf("%d\n",sizeof(struct student1));system("pause");return 0;}

内存对齐的原因吧。

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

2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要访问。


五. 位段

1、位段成员必须声明为int,signed int,unsigned int类型,在成员名的后面是一个冒号的一个整数,这个整数该位段所占用的大小。

2、首先,位段的成员在内存里面存储是从左到右还是从右到左的是不确定的,其次,当一个声明指定两个位段,第二个位段无法存储在第一个的剩余位上时,第二个位段直接存储于下一个字节上还是将第一个位段剩余的空间占满后剩下的存储到下一个字节也是不确定的。

因此,位段不能跨平台使用。

struct syudent{char a : 2;char b : 5;char c : 7;};

在vs平台上这个位段的大小为2个字节