龙空技术网

C语言结构体位域的简单介绍

行走的BUG永动机 457

前言:

眼前朋友们对“c语言中的结构体类型”大体比较重视,看官们都想要学习一些“c语言中的结构体类型”的相关内容。那么小编也在网上收集了一些有关“c语言中的结构体类型””的相关资讯,希望兄弟们能喜欢,看官们一起来学习一下吧!

0 前言

这几天看到一个有趣的结构体,之前没有见过,稍微了解了一下,顺便记录一下

==以下例子均在32位操作系统操作==

1 结构体简单介绍

在C语言中,每种类型的变量都会占用一定的字节数,以下面几种为例

char 1B int 4B double 8B

结构体简单将就是,用户自定义的复合数据类型,一个结构体中可以包含多种数据类型,最为常见的例子,就是学生信息表

结构体的声明方式如下

struct 结构体名称{        类型 成员1;    类型 成员2;         ...};

那么问题来了,结构体可以包含多种数据类型,那一个定义好的结构体会占用多少字节

比如下面这个例子

#include <stdio.h>struct example{ int a; int b; double c;};int main () {  printf("Size of example is %0d\n", sizeof(struct example)); return 0;}

在main函数中用sizeof打印一下结构体占用的字节数

先猜一下,int占4B,double占8B,计算下来应该是16B,来看运行结果

运行结果与预期相符

2 结构体的内存对齐

在CPU的存取的方式是以32bit(4 byte)为一次存取,也就是说,无论给定的data位宽为多少,CPU一次固定存取的位数固定为32bit

如果有数据超过32bit,CPU则会分多次存取

以下图为例,绿色的方框代表32bit

char的长度是1byte,2个char型变量共2 byte,没有超过32bit,所以CPU可以一次存取,因此这两个char型变量的地址偏移是连续的

下面用代码佐证

#include <stdio.h>struct example{ char a; char b; };int main () {  struct example p1;  printf("a: %0d\n", (size_t)&p1.a); printf("b: %0d\n", (size_t)&p1.b); return 0;}

仿真结果如下

可以看到,地址偏移数==增加1==

这里强调一下,「在计算机的地址中,是以byte为单位的」

接下来换个图

就像这样,如果在char后紧接着是一个int变量,那么此时结构体总共占用多少字节,int的地址偏移又是多少

#include <stdio.h>struct example{ char a; int b; };int main () {  struct example p1;  printf("\tSize of example is %0d\n", sizeof(p1)); printf("\ta: %0d\n", (size_t)&p1.a); printf("\tb: %0d\n", (size_t)&p1.b); return 0;}

先来猜测一下,如果不考虑内存对齐的因素,char占1 byte,int占4 byte,那结构体总的长度应该是5 byte

结果如下

可以看到二者的地址偏移并不是连续的,变量b的起始地址在a的下一个4 byte(地址偏移是负数)

并且,此时结构体的总长度是8 byte

3 结构体位域

下面来介绍一下结构体位域

结构体位域是用来将内存扣到极致的东西,在结构体位域中,可以自定义每个变量的位宽,并且是以bit为单位的

#include <stdio.h>struct example{  char  a : 5;  char  b : 3; };int main () {  struct example p1;  printf("\tSize of example is %0d\n", sizeof(p1)); return 0;}

在位域中,重新定义了a占 5 bit ,b占3 bit,那么整个结构体总共8bit,也就是1 byte

如果没有指定位域呢

#include <stdio.h>struct example{  char  a : 5;  char  b : 3; };int main () {  struct example p1;  printf("\tSize of example is %0d\n", sizeof(p1)); return 0;}

结果如下

本来打算打印下每个结构体成员的地址偏移的,结果

image-20230420235839679

不让打印,无法获取地址 >_<

原文链接

C语言结构体位域的简单介绍

标签: #c语言中的结构体类型