前言:
眼前朋友们对“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语言中的结构体类型