结构体字节对齐准则:

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. ArrayList底层实现

    ArrayList 底层是有数组实现,实际上存放的是对象的引用,而不是对象本身.当使用不带参的构造方法生成ArrayList对象时,实际会在底层生成一个长度为10的数组 当添加元素超过10的时候,会进 ...

  2. Boa服务器移植

    Boa是一种非常小巧的Web服务器,其可执行代码只有大约60KB左右.作为一种单任务Web服务器,Boa只能依次完成用户的请求,而不会fork出新的进程来处理并发连接请求.但Boa支持CGI,能够为C ...

  3. 【Linux笔记】linux crontab实现自动化任务

    在服务器中我们经常需要定时自动让程序自动进行数据备份.程序备份.执行某个进程等等操作,在linux服务器一般使用crontab实现,而windows下使用计划任务实现,crontab是linux系统下 ...

  4. DAY6-Python学习笔记

    前记: 坚持写学习笔记今天是第六天了,今天事情有点多想起来还没写赶快补起来,学习Python已经快一个星期了,大部分的知识点已经跟着廖雪峰老师的教程了解了一下,由于自学能力不强还有很多知识点掌握不牢固 ...

  5. [NOIP2011]玛雅游戏

    闲的没事干,出来写一下早两天刷的一道搜索题NOIP2011玛雅游戏,其实这道题还是比较水的,虽然看起来可能有点复杂. 方法很简单粗暴,直接根据规则模拟就行. 话不多说直接上代码(关键操作在注释中有提到 ...

  6. Java之使用链表实现队列

    import java.util.Iterator; import java.util.NoSuchElementException; /** * 使用链表来实现队列 * 1.考虑结点的结构,包括当前 ...

  7. 最新版的Android4.4.2 SDK无法下载解决

    http://hi.baidu.com/petercao2008/item/65362d2bdbddfacba5275a50 问题: Downloading ARM EABI v7a System I ...

  8. BAT脚本如何自动执行 adb shell 以后的命令

    @echo off echo su > temp.txt echo 其它命令 >> temp.txt adb shell < temp.txt del temp.txt 求问 ...

  9. MYSQL指定用户访问指定数据库

    1.使用navicat 1)首先使用root用户新建连接 2)新建mysql用户 3)点击权限,选择添加权限,出现MySQL中已存在的数据库列表,选择你要为该新建用户开放的数据库,此处选择“maiba ...

  10. Chapter3 (字符串,向量,数组) --C++Prime笔记

    1.using用法:using namespace ::name;注意事项:一般不在头文件使用using否则很容易导致运用命名空间不对错误. 2.string的方法: ①getline(输入流,str ...