C语言结构体知识科普

嵌入式技术

1362人已加入

描述

如何定义一个结构体?

定义一个结构体的方法有很多,这里我用一种常用的方式来定义结构体;

//定义一个结构体 结构名称是 student,
struct student
{
  char name[13];//char  类型 数组
  float fenshu; //float 类型 变量
  int  age;     //int   类型 变量
};

说明1:student 是一个结构的名称

说明2:student 这个结构里面的内容是结构体的成员列表

说明3:该结构体的成员列表由若干个成员组成,每个成员都是该结构的一个组成部分。

说明4:每个成员必须进行类型说明,这里有三种类型。

结构类型变量的说明

结构体定义并不是定义一个变量,而是定义了一种数据类型,这种类型是你定义的,它可以和语言本身所自有的简单数据类型一样使用(类似 int 类型)结构体本身并不会被作为数据而开辟内存,真正作为数据而在内存中存储的是这种结构体所定义的变量。

一个结构体变量占多大内存空间呢 ?

这是由这种结构体类型的定义决定的,可以想象为了同时存储结构体的每一个成员,那么结构体变量的存储大小,就应该是所有分量的存储空间的总合。

//定义一个结构体 结构名称是 student,
struct student
{
  char name[13];//char  类型 数组 13个字节
  float fenshu; //float 类型 变量 4个字节
  int  age;     //int   类型 变量 4个字节
};

字节总和 是 13 + 4 + 4 = 21个字节吗?

测试:

结构体

测试结果:

结构体

是代码有问题吗?还是理解有问题呢?

引入一个宏定义

offsetof(type, member-designator)

这是一个宏定义包含在里,它的作用是用来计算一个结构成员相对于结构开头的字节偏移量。

结构体

int main()
{
  printf("student 结构所占的内存大小   = %2d  字节\\r\\n",sizeof(student));


  printf("student 结构中的 name 偏移   = %2d  字节\\r\\n",offsetof(struct student, name));
  printf("student 结构中的 fenshu 偏移 = %2d  字节\\r\\n",offsetof(struct student, fenshu));
  printf("student 结构中的 age 偏移    = %2d  字节\\r\\n",offsetof(struct student, age));


  return(0);
}
//右滑查看所有代码

测试结果:

结构体

为什么分数的偏移是16而不是13?

字节对齐的概念

我们知道结构体是一种构造数据类型,里面可以有不同数据类型的成员。在这些成员中,不同的数据类型所占的内存空间是不同的。那么系统是怎么给结构体变量的成员分配内存的呢?或者说这些成员在内存中是如何存储的呢?通过上面这个例子我们知道肯定不是顺序存储的。那么到底是怎么存储的呢?就是按字节对齐的方式存储的!也就是以结构体成员中占内存最多的数据类型所占的字节数为标准,所有的成员在分配内存时都要与这个长度对齐。

举一个例子:我们以上面这个程序为例,结构体变量 student的成员中占内存最多的数据类型是 int 型,跟float一样,其占 4 字节的内存空间,那么所有成员在分配内存时都要与 4 字节的长度对齐。也就是说,虽然 char 只占 1 字节,但是为了与 4 字节的长度对齐,它会占用

4个字节+

4个字节+

4个字节+

1个字节+补3个字节 总共 = 16个字节

有关字节对其的详细分析,下次再聊,今天就来说一下如何让其按照我们想的单个字节对其

单个字节对其

我们可以使用伪指令#pragma pack(n)(n为字节对齐数)使得结构间一字节对齐

使用方法:

结构体

再次测试:

结构体

好了时间有限,今天就写到这,下周我们再聊结构体的多种定义和使用方法。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分