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. 箫声远(本人)的小站(为展示作品、简历,基于github pages)

    箫声远的个人前端小站在线地址

  2. PAT甲级【2019年9月考题】——A1160 Forever【20】

    7-1 Forever (20 分) "Forever number" is a positive integer A with K digits, satisfying the ...

  3. 方法Join()

    等待线程结束:jion() 谦让: yeild() 睡眠: sleep() jion和sleep和yeild之间有什么区别呢? 首先介绍一下jion(): 如果想让主线程等待子线程执行完毕之后再继续运 ...

  4. MySQL 同一字段匹配多个值

    delete from api_log WHERE curl LIKE '%.css' or curl LIKE '%.js' or curl LIKE '%.JPG'; 删除字段curl以 js,c ...

  5. JS面向对象——构造函数模型

    ECMAScript中的构造函数可用来创建特定类型的对象.我们可以创建自定义构造函数,从而定义对象类型的属性和方法,解决工厂模型中对象识别的问题. <!DOCTYPE html> < ...

  6. Flask+elasticsearch实现搜索引擎入门教程+Curl调试

    前几天,在github上看到了一个关于elasticsearch的小项目,有点小兴趣,于是就结合着Flask,研究了一下,分享给大家. 准备资料: 1.安装elasticsearch 参考教程:htt ...

  7. 如何将自己的代码上传至github

    前提条件: 有个github账号,电脑安装了git; 首先在自己的账号里新建一个仓库: https://github.com/qiqi105/littleAlbum.git 进入到你要上传的文件夹内部 ...

  8. noip2018火柴棒等式

    以下题目摘自洛谷p1149 给你n根火柴棍,你可以拼出多少个形如“A+B=CA+B=C”的等式?等式中的AA.BB.CC是用火柴棍拼出的整数(若该数非零,则最高位不能是00).用火柴棍拼数字0-90− ...

  9. vue-router中的router-link的active-class

    vue-router中的router-link的active-class   在vue-router中要使用选中样式的方法有两种: 1.直接在路由js文件中配置linkActiveClass 2.在r ...

  10. STL笔试面试题总结(干货)(转)

    STL笔试面试题总结 一.STL有哪些组件? STL提供六大组件彼此此可以组合套用: 1.容器容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class ...