摘要:

经常被计算结构体的sizeof给搞晕,于是找了个时间,静下心来,搞定它。

一、为什么结构体计算这么乱?

答案是字节对齐,计算机存储系统中以Byte为单位存储数据,不同数据类型所占的空间不同,如:整型(int)数据占4个字节,字符型(char)数据占一个字 节,

短整型(short)数据占两个字节,等等。计算机为了快速的读写数据,默认情况下将数据存放在某个地址的起始位置,如:整型数据(int)默认存储 在地址能被

4整除的起始位置,字符型数据(char)可以存放在任何地址位置(被1整除),短整型(short)数据存储在地址能被2整除的起始位置。这样字节对齐有助于加快

计算机的取数速度,否则就得多花指令周期了。

二、字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:

1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2. 结构体每个成员相对于结构体首地址的偏移量都是当前成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;

3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。

说明:1、基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型;

2、对于复合数据类型,如结构体嵌套结构体,那么基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型;

3、我认为计算结构体大小的时候,主要用到准则2和准则3,对于准则1是编译器自动完成的,不需要过多理会。

4、C++中类的可以看做是特殊的结构体,所以类的sizeof的计算和结构体是一样的。

三、下面拿具体的程序来详细说明:

// sizeof(结构体).cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include<iostream>
using namespace std;struct A
{char a;int b;
};
struct B
{char a;A a1;char b;
};
int _tmain(int argc, _TCHAR* argv[])
{cout<<sizeof(A)<<endl<<sizeof(B);return 0;
}

上述程序的输出结果是8和16.

下面结合前面给出的准则具体分析一下。

对于结构体A其基本成员类型有char和int两种,最宽的是int占用4个字节,那么根据准则1,编译器会自动为结果体A分配一个能被4整除的首地址,A的第一个成员char的首地址就是结构体A的首地址,即偏移量为0,接下来,下一个成员变量int首地址,如果不做处理的话,应该是相对于A的偏移量是1,这就不满足准则2了,所以编译器开始在char的后面填充3个字节,使得int相对于A的偏移量是4,来满足准则2,然后结构体的总大小就是1(char)+3(填充)+4(int)=8,同时满足了准则3,不用再填充了,所以sizeof(A)=8。

对于结构体B,其中包括了一个复合类型,查看基本类型的时候,要将其中的结构体A拆分成char和int两种类型来看,所以结构体B中的基本数据类型是char,char,int,char,最宽的数据类型是int,编译器会自动为B分配一个能被4整除的首地址,B的第一个成员char的首地址就是结构体B的首地址,即偏移量为0,接下来,下一个成员变量A的首地址,如果不做处理的话,应该是相对于B的偏移量是1,这就不满足准则2了,所以编译器开始在char的后面填充3个字节,使得成员A相对于所在结构体B的地址偏移量是4,来满足准则2,这时加上B的长度8,B中最后一个成员char相对于B来说地址偏移量是8,能满足准则2,所以不需要在A的后面填充字节,这时B的总长度是1(char)+3(填充)+8(A)+1(char)=13,不满足准则3,所以还需要在最后一个char后面再添加3个字节,最后得到B的总大小是1(char)+3(填充)+8(A)+1(char)+3(填充)=16,所以sizeof(B)=16。

【C/C++】sizeof(结构体)的计算相关推荐

  1. 内存对齐的原理,作用,例子以及一些规划(中英文说明,适用sizeof结构体) ...

    目录   题记  一  内存读取粒度   Memory access granularity   从内存的角度解释内存对齐的原理   队列原理 Alignment fundamentals   Laz ...

  2. c语言中sizeof结构体,C语言中的sizeof用法

    C语言中的sizeof是一个很有意思的关键字,经常有人用不对,搞不清不是什么.我以前也有用错的时候,现在写一写,也算是提醒一下自己吧.反正现在来看,还在搞sizeof是什么意思,怎么用正确,还是有点搞 ...

  3. 【C 语言】结构体 ( 结构体偏移量计算 | 代码示例 )

    文章目录 一.结构体成员偏移量 二.完整代码示例 一.结构体成员偏移量 获取 Student 结构体中 age 成员偏移量 有 222 种写法 ; 结构体样式 : typedef struct Stu ...

  4. [YTU]_2865( 结构体--日期计算)

    已经声明了一个日期的结构体类型,如下 struct  Date{ int year; int month; int day; }; 定义一个日期变量,进行年.月.日的输入,计算该日期是本年中的第几天. ...

  5. 结构体:计算学生平均分

    Description 定义一个学生结构体,含学号(字符型).姓名.2门课程的成绩.从键盘输入3个学生的信息,计算并输出每个学生的平均成绩. Input 按学号.姓名.成绩1.成绩2的顺序输入学生信息 ...

  6. 输入一个天数计算几周零几天 C语言,结构体练习——计算输入的日期为本年度第几天...

    /*需求:特定的某天是该年的第几天 输入:年月日 输出:根据输入计算它是本年的第几天 */ #include using namespace std; struct Date {//使用结构体定义输入 ...

  7. C语言sizeof结构体大小计算

    一.一般类型 约定为32位系统,即char 1字节.short 2字节.int 4字节,指针是地址4个字节 定义:偏移量 偏移量指的是结构体变量中成员的地址和结构体变量地址的差.结构体大小等于最后一个 ...

  8. 结构体对齐计算(超详细讲解,一看就会)

    想要计算结构体大小,咱就先要清楚结构体内存对齐的规则: 1.结构体的第一个成员直接对齐到相对于结构体变量起始位置为0处偏移. 2.从第二个成员开始,要对齐到某个[对齐数]的整数倍的偏移处. 3.结构体 ...

  9. 第十六周 结构体复数计算

    Copyright (c) 2016 烟台大学计算机与控制工程学院 All rights reserved. 文件名称:test.cpp 作者:何定钦 完成日期:2016年12月16日 题目描述:编写 ...

  10. sizeof结构体指针

    #include "stdio.h" typedef struct test_t{int a;int b;int c;int d; }mytest; int main() {myt ...

最新文章

  1. 三个事件同步实现双相机同步WaitForMultipleObjects
  2. Halcon初学者知识【15】图像的定义域Domain
  3. 拖拽元素自定义html模板,JS实现的自定义网页拖动类
  4. mysql的pager命令,mysql pager用法命令行命令
  5. 用Helper对类的行为进行修饰以便复用(附:外三篇)
  6. matlab将模型解封装,模型保护 - MATLAB Simulink - MathWorks 中国
  7. 用virt-manager管理远程KVM虚拟机
  8. 小甲鱼 python11讲作业
  9. 《物联网Android程序开发案例式教程》Demo3:登录页面
  10. spring项目启动慢问题
  11. yolov5样本处理方式
  12. LaTeX插入大尺寸JPG图片出现纵横比异常水平被压缩的解决方法
  13. 苹果商城怎么调成中文_深入探讨:承德洋葱电商平台怎么开店
  14. 2020年代,中国AI创业公司将走向何方
  15. 使用Arduino开发板进行语音识别
  16. 文旅元宇宙热潮来袭,天下秀用“科技之钥”解锁三大价值
  17. 梳理学习技术的脉络,助你一臂之力
  18. spring中的事件监听机制
  19. c语言代码 txt下载,俄罗斯方块C语言源代码txt.DOC
  20. 如何回答:你有什么样的职业规划

热门文章

  1. pytorh——Fully-connected
  2. 【课本】【No.3】随机向量定义、联合分布函数、边缘分布、统计特征的分布函数的差分,独立性、离散型条件分布列,连续型分布函数与密度函数、随机向量的函数分布
  3. bat文件启动虚拟环境然后继续在虚拟环境里进行操作采用CALL
  4. 剑指offer题解 带讲解 python版 第二部分
  5. 从web页面请求的历程出发了解计算机网络的基础知识
  6. logistics 与最大熵模型原理及python代码实现
  7. Java 并发和多线程(一) Java并发性和多线程介绍[转]
  8. SecureCRT 颜色
  9. .NET Remoting学习笔记(二)激活方式
  10. ATOM使用的一点心得与技巧——在一个窗口打开多个项目