struct
结构体的大小不是简单的成员相加,要考虑存储空间的字节对齐
1、空结构体的大小为1
2、含有static的结构体在计算大小时不算上static变量,因为static存储在全局数据空间,而sizeof计算的是栈分配的空间

一、编译器存储结构体的准则(很重要):
  •  结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
  •  结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
例如:|【char】【char】【x】【x】【           int            】|
    |【                                  double                                】|
int类型不会直接接在最后一个char后面,它会在与结构体首地址的偏移量为其倍数的地方开始存储
  •  结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。

二、结构体长度求法

1.成员都相同时(或含数组且数组数据类型同结构体其他成员数据类型):

结构体长度=成员数据类型长度×成员个数(各成员长度之和);

结构体中数组长度=数组数据类型长度×数组元素个数;

2.成员不同且不含其它结构体时;

(1).分析各个成员长度;

(2).找出最大长度的成员长度M(结构体的长度一定是该成员的整数倍);

(3).并按最大成员长度出现的位置将结构体分为若干部分;

(4).各个部分长度一次相加,求出大于该和的最小M的整数倍即为该部分长度

(5).将各个部分长度相加之和即为结构体长度

3.含有其他结构体时:

(1).分析各个成员长度;

(2).对是结构体的成员,其长度按b来分析,且不会随着位置的变化而变化;

(3).分析各个成员的长度(成员为结构体的分析其成员长度),求出最大值;

(4).若长度最大成员在为结构体的成员中,则按结构体成员为分界点分界;

其他成员中有最大长度的成员,则该成员为分界点;

求出各段长度,求出大于该和的最小M的整数倍即为该部分长度

(5).将各个部分长度相加之和即为结构体长度


例子:
struct test1{ char a; 
   int b; 
   double c; 
   bool d; 
  };

 

分析:该结构体最大长度double型,长度是8,因此结构体长度分两部分:

第一部分是a、 b、 c的长度和,长度分别为1,4,8,则该部分长度和为13,取8的大于13的最小倍数为16;

第二部分为d,长度为1,取大于1的8的最小倍数为8,

两部分和为24,故sizeof(test2)=24;

struct  test2{ 
 char a; 
  test1 bb;
 int cc; 
}

分析:该结构体有三个成员,其中第二个bb是类型为test1的结构体,长度为24,且该结构体最大长度成员类型为double型,以后成员中没有double型,所以按bb分界为两部分:

第一部分有a 、bb两部分,a长度为1,bb长度为24,取8的大于25的最小倍数32;

第二部分有cc,长度为4,去8的大于4的最小倍数为8;

两部分之和为40,故sizeof(test3)=40;

struct test4{ 
 char a; 
 int b; 
}; 
struct test5{ char c; 
 test4 d; 
 double e; 
 bool f; 
};


求sizeof(test5)

分析:test5明显含有结构体test4,按例2容易知道sizeof(test4)=8,且其成员最大长度为4;则结构体test5的最大成员长度为8(double 型),考试.大提示e是分界点,分test5为两部分:

第一部分由c 、d、e组成,长度为1、8、8,故和为17,取8的大于17的最小倍数为24;

第二部分由f组成,长度为1,取8的大于1的最小倍数为8,

两部分和为32,故sizeof(test5)=24+8=32;


union

union的长度取决于其中的长度最大的那个成员变量的长度。即union中成员变量是重叠摆放的,其开始地址相同。

其实union(共用体)的各个成员是以同一个地址开始存放的,每一个时刻只可以存储一个成员,这样就要求它在分配内存单元时候要满足两点:

  1.一般而言,共用体类型实际占用存储空间为其最长的成员所占的存储空间;  
  2.若是该最长的存储空间对其他成员的元类型(如果是数组,取其类型的数据长度,例int   a[5]为4)不满足整除关系,该最大空间自动延伸;  
例如:
union un
{
    int a[7]; //元长度4
    double b; //元长度8
    char c[10]; //元长度1
    int d[3]; //元长度4
};
可求得sizeof(un)=32;
 
union number
{ /*定义一个联合*/
int i;
struct
{ /*在联合中定义一个结构*/
char first;
char second;
}half;
}num;
可求得sizeof(number)=4, 其中大致的结构是这样的:
(高地址)【高位---------int------------低位】(低地址)
或者
(高地址)【--】【--】【-second-】【-first-】(低地址)
同一时间只有一种情况,因为union每一时刻只能存储一个成员
例子代码:

#include <stdio.h>

void main()

{

union number

{ /*定义一个联合*/

int i;

struct

{ /*在联合中定义一个结构*/

char first;

char second;

}half;

}num;

num.i=0x4241; /*联合成员赋值*/

printf("%c%c/n", num.half.first, num.half.second);

num.half.first='a'; /*联合中结构成员赋值*/

num.half.second='b';

printf("%x/n", num.i);

getchar();

}
输出结果为: 

AB 

6261

从上例结果可以看出: 当给i赋值后, 其低八位也就是first和second的值; 当给first和second赋字符后, 这两个字符的ASCII码也将作为i 的低八位和高八位。




(本文章整合了网上的一些资料并加上了自己的一些理解)

Struct和Union的sizeof计算的更多相关文章

  1. sizeof 计算 struct 占字节数的方法总结

    矛盾焦点: 1.结构体的内存对齐方式 字节对齐的目的: 1.提高CPU存储变量的速度 计算的核心点(默认对齐方式): 1.结构体内的每一个成员的起始地址跟结构体起始地址的偏移量要刚好是自己字节数的整数 ...

  2. 关于C中struct和union长度的详解

    这几天看<代码大全>中的第十三章---不常见的数据类型,里面讲解到了C语言中的struct以及对指针的解释,联想到以前看过相关的关于C语言中stuct长度的文章,只是现在有些淡忘了,因此今 ...

  3. 【转】C/C++ struct/class/union内存对齐

    原文链接:http://www.cnblogs.com/Miranda-lym/p/5197805.html struct/class/union内存对齐原则有四个: 1).数据成员对齐规则:结构(s ...

  4. sizeof计算空间大小的总结

    sizeof,看起来还真不简单,总结起来还是一大堆的东西,不过这是笔试面试中出现比较频繁的,我也是考过才觉得很重要,有些规则如果不注意,还真是拿到一道题目摸不着头脑,所有总结一下,方面忘记的时候瞄一瞄 ...

  5. <转> Struct 和 Union区别 以及 对内存对齐方式的说明

    转载地址:http://blog.csdn.net/firefly_2002/article/details/7954458 一.Struct 和 Union有下列区别: 1.在存储多个成员信息时,编 ...

  6. sizeof()计算

    本节包含sizeof()计算结构体,位域,数组,字符串,指针,c++中的class等类型的大小,sizeof()计算的大小都是以字节为单位. 一 计算基本类型的长度 sizeof(char): 1 s ...

  7. [转]sizeof计算空间大小的总结

    原文链接:http://www.cnblogs.com/houjun/p/4907622.html 关于sizeof的总结 1.sizeof的使用形式:sizeof(var_name)或者sizeof ...

  8. 第10课 struct 和 union 分析

    1. struct的小秘密 (1)C语言中的struct可以看作变量的集合 (2)struct的问题——空结构体占用多的内存? [实例分析]空结构体的大小 #include <stdio.h&g ...

  9. 第10课 struct和union分析

    struct的小秘密:空结构体占多大内存呢? 直观的答案有两种: 1.空结构体的大小为0 2.结构体本来就是为了将不同的变量集合在一起使用的,定义空结构体会导致编译错误 实例分析: #include ...

随机推荐

  1. ustc FreeBSD / rust 镜像源

    http://mirrors.ustc.edu.cn/help/ Rust Crates 源使用帮助 地址 https://mirrors.ustc.edu.cn/crates.io-index/ 说 ...

  2. 干货 | Bokeh交互式数据可视化快速入门

    Bokeh简介 Bokeh是一款交互式可视化库,在浏览器上进行展示. Bokeh可以通过Python(或其它语言),快速便捷地为大型流数据集提供优雅简洁的高性能交互式图表. 安装 在python中有多 ...

  3. Webshell免杀

    过狗过D盾 <?php class me{ public $a = ''; function __destruct(){ assert("$this->a"); }}$ ...

  4. tar.xz 解压

    解压tar.xz文件:先 xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx.tar 然后,再用 tar xvf xxx.tar来解包. xz -d Python-3.7.1.t ...

  5. leetcode.图.785判断二分图-Java

    1. 具体题目 给定一个无向图graph,当这个图为二分图时返回true.如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这 ...

  6. mySQL查看存储过程、函数、视图、触发器

    一.查看存储过程 1.show procedure status; //查看所有的 2.show create procedure proc_AllUser[proc_name]; 查看proc_Al ...

  7. Sql Server Management Studio 18 打开闪退问题

    解决方案 找到MSSMS安装位置,例如我是安装到了D:\Program Files (x86)\Microsoft SQL Server Management Studio 18 将D:\Progra ...

  8. 简易的富文本编辑器WangEditor

    网址http://www.wangeditor.com/ var E = window.wangEditor; var editor = new E('#editor') // 或者 var edit ...

  9. 使用pytorch测试单张图片(test single image with pytorch)

    以下代码实现使用pytorch测试一张图片 引用文章: https://www.learnopencv.com/pytorch-for-beginners-image-classification-u ...

  10. Ubuntu修改用户和root密码

    如果要修改root的密码:sudo passwd 如果要修改_当前_用户的密码:passwd 如果要修改其他用户的密码(你得有权限):sudo passwd USERNAME,USERNAME就是你要 ...