结构体字节对齐准则:

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

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

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

4. 在嵌套结构中需要把内部‘打散'后再进行对齐计算。

// 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 ;
}

上述程序的输出结果是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。

结构体技巧:结构体支持整体赋值,因此可以利用结构体来处理数组的整体赋值操作。

结构体变量的sizeof计算的更多相关文章

  1. C语言中 不定义结构体变量求成员大小

    所谓的求成员大小, 是求成员在该结构体中 用 sizeof(结构体名.结构体成员名) 求来的. 很多时候我们需要知道一个结构体成员中的某个成员的大小, 但是我们又不需要定义该结构体类型的变量(定义的话 ...

  2. C语言结构体变量字节对齐问题总结

    结构体字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但 ...

  3. 【C++】结构体、联合体大小计算

    struct结构体大小计算 struct A { char a; int b; char c; } 这个结构体中,char占据1字节,int占据4字节,char占据1字节,而这组数据结构的大小是12字 ...

  4. (60) 结构体指针、结构体变量嵌套、结构体指针嵌套、函数指针、数组指针、指针数组、typedef 综合运用

    #include<stdio.h> #include<iostream> #include<malloc.h> /* author : 吴永聪 program: 结 ...

  5. C语言结构体变量私有化

    操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 问题描述 C语言结构体定义中的变量默认是公有(Public)属性,如果实现成员变量的私有(Private)化? 解决方案 ...

  6. 结构体变量的 extern 使用方法,转--

    要求如下,在.h文件中这样定义: typedef struct typFNT_GB16     // 汉字字模数据结构 {     signed ];        // 汉字内码索引     ]; ...

  7. C结构体变量2种运算(比如链表的结点)(区别与java)

    a结构体变量,只能做两种运算, 整体引用(赋值,参数传递) 或访问成员(点运算—地址方式简化,地址方式)(见最后的图片) case万: 结论:java里面的class Node : Node p; p ...

  8. C语言中两个相同类型的结构体变量之间是可以相互直接赋值的

    C语言中,在相同类型的变量间赋值时是直接内存复制的,即将他们的内存进行复制,而两个同类型的结构体变量属于同一种变量,所以赋值时是按照他们的内存分布来直接拷贝的.所以,在C语言中两个相同类型的结构体变量 ...

  9. 在C代码中将结构体变量作为参数传递效率忒低

    在C语言编程中,我们几乎不可能看见有人将一个结构体变量作为参数进行传递,因为效率太低了.本文尝试从反汇编的角度给出其中的缘由. 对于C语言来说,所有的参数传递都是值传递.如果一个变量为指针,那么传递的 ...

随机推荐

  1. 在服务器搭建Jupyter notebook

    安装 Jupyter Notebook (这里虽然是对centos和Python2的,但是在Ubuntu16.04,Python3同样可以照着弄) Jupyter Notebook 简介 Jupyte ...

  2. html select options & vue h render

    html select options & vue h render https://developer.mozilla.org/en-US/docs/Web/HTML/Element/opt ...

  3. STM32标准外设库、 HAL库、LL库

    工作以来一直使用ST的STM32系列芯片,ST为开发者提供了非常方便的开发库.到目前为止,有标准外设库(STD库).HAL库.LL库 三种.前两者都是常用的库,后面的LL库是ST最近才添加,目前支持的 ...

  4. MySQL 5.6 & 5.7最优配置文件模板

    Inside君整理了一份最新基于MySQL 5.6和5.7的配置文件模板,基本上可以说覆盖90%的调优选项,用户只需根据自己的服务器配置稍作修改即可,如InnoDB缓冲池的大小.IO能力(innodb ...

  5. springmvc+mybatis 处理图片(一):上传图片

    一直觉得上传图片文件之类的很难,所以最后才处理图片,发现也并没有那么难,开始正文. 思路:将前台上传的file存到MutipartFile类型字段中,再将MulipartFile转换为pojo类中的b ...

  6. js复制内容到剪切板

    注意第一部分的内容不兼容Safari,全兼容的请使用第二部分方法 第一部分 查看demo请点  这里. 原生js复制指定内容到剪切板,超简单的实现方式, 实现思路如下: 1.创建一个input,把想要 ...

  7. java链表的各种操作

    java里面没有指针的说法,所以初始化的时候,就是新建一个null节点就是一个空链表了.//C里面链表会有头指针,头指针指向头节点 如果想向空链表插入第一个节点,直接head=newNode: 注意的 ...

  8. c++11 语言级线程

    c++11 语言级线程 线程的创建 用std::thread创建线程非常简单,只需要提供线程函数或函数对象即可,并且可以同时指定线程函数的参数. #define _CRT_SECURE_NO_WARN ...

  9. Spring点滴六:Spring中定义bean的继承

    在基于XML配置元数据中,bean标签可以包含很多配置信息,可以包含构造函数的参数,属性值以及其他一些初始化方法.子bean的定义可以继承父bean定义元数据,子bean定义可以根据需要重写父bean ...

  10. 洛谷 P4292 [WC2010]重建计划 解题报告

    P4292 [WC2010]重建计划 题目描述 \(X\)国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.\(X\)国由\(N\)个城市组成, 重建小组提出,仅需建立\(N-1\ ...