C_结构体

来源:互联网 发布:中介软件哪个好 编辑:程序博客网 时间:2024/05/29 18:02

结构体详解目录:

  1. 结构体对齐步骤
  2. 结构体定义
  3. 访问结构体内成员
  4. 结构体初始化

结构体在项目中大量运用:
原来单纯的以为全是四字节对齐,其实不然。

1、结构体对齐步骤:

1)将结构体内所有数据成员的长度值相加,记为sum_a;

2)将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是#pragma pack指定的数值以及该数据成员自身长度中数值较小者。该数据相对起始位置应该是对齐模式的整数倍;

3)将和sum_b向结构体模数对齐,该模数是【#pragma pack指定的数值】、【未指定#pragma pack时,系统默认的对齐模数(32位系统为4字节,64位为8字节)】和【结构体内部最大的基本数据类型成员】长度中数值较小者。结构体的长度应该是该模数的整数倍。

例子:

struct my_struct { char a[11]; int b; char c; }; 

此例子Windows和Linux计算方法一样,如下: 步骤1:所有数据成员自身长度和:11B + 4B + 1B = 16B --> sum_a = 16B 步骤2:数据成员a放在相对偏移0处,之前不需要填充字节;数据成员b为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是4,之前需填充3个字节,sum_a + 1 = 17B --> sum_b = 17B 步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pragma pack中较小者,前者为4后者为4,所以结构体对齐模数是4。sum_b是4的整数倍,需在结构体后填充4*5 - 17 = 1个字节。 综上3步,可知结构体的长度是20B,各数据成员在内存中的分布如图4所示。 

2、结构体定义:

struct student{    int     id;    char    name[32];    int age;};   //传统的结构体格式定义。

struct test{    int     a;    float   b;    char    c;}var;   //在定义结构的同时定义变量,该变量目前是全局变量

typedef struct  abc{    int a;    int b;}NEW_TYPE; //NEW_TYPE == struct abc 


3、访问结构体内的成员:

  struct test{    int     a;    float   b;    char    c;}var , *p;   //在定义结构的同时定义变量,该变量目前是全局变量

结构体变量中定义了普通变量var和指针变量p

于是访问var写法:

var.avar.bvar.c

而访问指针变量p中元素写法:

(*p).a(*p).b(*p).c

本来访问格式一样,但为了简洁c语言有了下写法:

p->ap->bp->C

再说第四个方法,也是我在项目中学习到的:

就是直接访问内存地址

首先你确定这个结构体是多少字节,几字节对齐。

sizeof(DataSPSum) = 12;

4字节对齐。

正常的访问赋值方法是:

现在换一种方式:

int *p1 = (int *)&temp;

访问的时候就是*(p) 是访问的temp.sp.STDSP*(p+1)是访问的temp.sp.STMSP*(p+2)是访问的temp.sum

现在我们把成员数据类型换一下,访问就变了

char *p1 = (char *)&temp

访问的时候就是*(p) 是访问的temp.sp.STDSP*(p+2)是访问的temp.sp.STMSP*(p+4)是访问的temp.sum

4、结构体初始化:

这里介绍构造函数

构造函数:就是用来初始化结构体的一种函数,它直接定义在结构体内,它的特点是不需要写返回类型,且函数名也结构体相同。

struct studentInfo{    int id;    char gender;    studentInfo(){} //用以不初始化就定义结构体变量    studentInfo(int _id,char _gender): id(_id),gender(_gender){}}pt;

pt = studentInfo(1,'a');

还有就是直接赋值

这里看一个项目中精简的定义赋值方法:

原创粉丝点击