数据结构 / 结构体字节计算

1. 结构体的存储

  • 结构体各个成员的地址是连续的
  • 结构体变量的地址是第一个成员的地址

2. 64位操作系统8字节对齐

  • 结构体的总字节大小是各个成员字节的总和,字节的总和需要是最宽成员的倍数
  • 结构体的首地址是最宽成员的倍数
  • 结构体各个成员的偏移量是该成员字节的倍数,否则填充空字节

例子1:

cpp 复制代码
#include <string.h>
#include <stdlib.h>
#include <stdio.h>


struct A
{
    int a; //4 
    char b; //1 
    short c; //2 
    float d; //4 

}a;


int main(int argc, const char *argv[])
{
    printf("a=%p\n", &a);
    printf("a.a=%p\n", &a.a);
    printf("a.b=%p\n", &a.b);
    printf("a.c=%p\n", &a.c);
    printf("a.d=%p\n", &a.d);
    printf("sizieof(a)=%ld\n", sizeof(a));
    
    return 0;
}          

计算

运行结果

cpp 复制代码
a=0x55b0037eb018
a.a=0x55b0037eb018
a.b=0x55b0037eb01c
a.c=0x55b0037eb01e
a.d=0x55b0037eb020
sizieof(a)=12

例子2:

cpp 复制代码
#include <string.h>
#include <stdlib.h>
#include <stdio.h>


struct A
{
    int *a; //8 
    char b; //1 
    double c; //8 
    long d; //8 

} s1; 


int main(int argc, const char *argv[])
{
    printf("s1=%p\n", &s1);
    printf("s1.a=%p\n", &s1.a);
    printf("s1.b=%p\n", &s1.b);
    printf("s1.c=%p\n", &s1.c);
    printf("s1.d=%p\n", &s1.d);
    printf("sizieof(s1)=%ld\n", sizeof(s1));
    
    return 0;
}  

计算

运行结果

cpp 复制代码
s1=0x55e754e4e040
s1.a=0x55e754e4e040
s1.b=0x55e754e4e048
s1.c=0x55e754e4e050
s1.d=0x55e754e4e058
sizieof(s1)=32

例子3:

cpp 复制代码
#include <string.h>                                                                       
#include <stdlib.h>
#include <stdio.h>


struct S
{
    char a[5]; //
    int b; //

} s3; 


int main(int argc, const char *argv[])
{
    printf("s3=%p\n", &s3);
    printf("s3.a=%p\n", &s3.a);
    printf("s3.b=%p\n", &s3.b);
    printf("sizieof(s3)=%ld\n", sizeof(s3));
        
    return 0;
}

计算

运行结果

cpp 复制代码
s3=0x55da08b43018
s3.a=0x55da08b43018
s3.b=0x55da08b43020
sizieof(s3)=12

3. 32位操作系统,4字节对齐:

  • 结构体的总字节大小是各个成员字节的总和,字节的总和需要是最宽成员的倍数
    • 如果最宽成员是1,则是1的倍数
    • 如果最宽成员是2,则是2的倍数
    • 如果最宽成员是4,8,则是4的倍数
  • 结构体的首地址是最宽成员的倍数
  • 结构体各个成员的偏移量是该成员字节的倍数,否则填充空字节
    • 如果成员字节是1,则偏移量是1的倍数
    • 如果成员字节是2,则偏移量是2的倍数
    • 如果成员字节是4,8,则偏移量是4的倍数

例子4:

cpp 复制代码
#include <string.h>
#include <stdlib.h>
#include <stdio.h>


struct S5
{
    char a; //
    int *b; 
    double c;
    long d;
        

}s5 ;

struct S6
{
    char e[5];
    struct S5 s5; 
    int f;

}s6;


int main(int argc, const char *argv[])
{
    printf("s6.e=%p\n", &s6.e);
    printf("s6.s5.a=%p\n", &s6.s5.a);
    printf("s6.s5.b=%p\n", &s6.s5.b);                                                     
    printf("s6.s5.c=%p\n", &s6.s5.c);
    printf("s6.s5.d=%p\n", &s6.s5.d);
    printf("s6.f=%p\n", &s6.f);
    printf("sizieof(s6)=%ld\n", sizeof(s6));
        
    return 0;
}
~    

计算

运行结果

cpp 复制代码
s6.e=0x565cf040
s6.s5.a=0x565cf048
s6.s5.b=0x565cf04c
s6.s5.c=0x565cf050
s6.s5.d=0x565cf058
s6.f=0x565cf05c
sizieof(s6)=32
相关推荐
whoarethenext4 分钟前
使用 C/C++的OpenCV 实现模板匹配:从基础到优化
c语言·c++·opencv
Clownseven29 分钟前
Ubuntu 24.04 LTS 长期支持版发布:对服务器用户意味着什么?新特性、升级建议与性能影响初探
linux·服务器·ubuntu
Xam_d_LM33 分钟前
【Linux】服务器反向代理自动续签免费 Let‘s Encrypt 证书报错解决方法
linux·运维·服务器·反向代理·lets encrypt·http-01·证书续签
有时有晌42 分钟前
linux arm系统烧录
linux·运维·arm开发
合方圆~小文1 小时前
架空线路图像视频监测装置
c语言·c++·人工智能·嵌入式硬件·硬件工程·模拟退火算法
卖猪肉的痴汉2 小时前
4.2 C/C++开发环境:VSCode+CMake+MSYS2
c语言·c++·vscode
ღ 噫吁嚱2 小时前
【C/C++】实现固定地址函数调用
c语言·开发语言·c++
小呆瓜历险记2 小时前
Debian系统简介
linux·服务器·debian
黑牛先生2 小时前
【数据结构】图算法(代码)
数据结构·算法
DanmF--2 小时前
用C#实现单向链表和双向链表
数据结构·链表·c#