sizeof(结构体)的计算
摘要:
经常被计算结构体的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 ;
}
上述程序的输出结果是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(结构体)的计算的更多相关文章
- sizeof(结构体)和内存对齐以及位域
Win32平台下的微软C编译器的对齐策略: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该 ...
- sizeof结构体
规则1:结构体的对折长度为其基本数据成员的长度的最大值. 规则2:指定边界情况下,结构体的对折长度为自身对折长度和指定对折长度中较小者. 规则3:当行内结构体的基本数据成员的起始地址必须为其长度的整数 ...
- Problem D: 结构体:计算输入日期是该年的第几天
#include <stdio.h> struct time{ int year; int month; int day;}; int main(void) { struct time s ...
- 结构体变量的sizeof计算
结构体字节对齐准则: 1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 2. 结构体每个成员相对于结构体首地址的偏移量都是当前成员大小的整数倍,如有需要编译器会在成员之间加上填充字节: ...
- 全面总结sizeof的用法(定义、语法、指针变量、数组、结构体、类、联合体、位域位段)
一.前言 编译环境是vs2010(32位). <span style="font-size:18px;">#include<iostream> #inclu ...
- 结构体,公用体,枚举类型的sizeof
1)枚举类enum型空间计算 enum只是定义了一个常量集合,里面没有“元素”,而枚举类型是当做int来存储的,所以枚举类型的sizeof值都为4 enum color(red,pink,white, ...
- C++结构体中sizeof(1)
sizeof sizeof操作符的作用是返回一个对象或类型名的长度,长度的单位是字节. 返回值的类型是标准库命名为size_t的类型,size_t类型定义在cstddef头文件中,该头文件是C标准库的 ...
- C++面试常见问题——13结构体与共用体的sizeof
结构体与共用体的sizeof 结构体的sizeof 结构体变量占用的内存空间大小通常是其基本类型的大小,但是由例外(字节对齐机制) struct S1{ char c[5]; int a; doubl ...
- C语言中结构体对齐问题
C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...
随机推荐
- select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET (转)
select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型,原型: #include <sys/time.h> ...
- 链接中 href='#' 和 href='###' 的区别以及优缺点
首先,<a> 标签 + onclick='{jscode}' 是很常用的一种 js 运用方式,而不使用 href='javascript:{jscode}' 是为了兼容多种浏览器对 < ...
- php三维数组去重(示例代码)
php三维数组去重的示例代码. 假设叫数组 $my_array; <?php // 新建一个空的数组. $tmp_array = array(); $new_array = array(); ...
- scrapy-redis使用详解
描述: 1.使用两台机器,一台是win10,一台是centos7,分别在两台机器上部署scrapy来进行分布式抓取一个网站 2.centos7的ip地址为192.168.1.112,用来作为redis ...
- LeetCode之Single Number以及拓展
Problem 1:一个数组中有一个数字a只出现一次,其他数字都出现了两次.请找出这个只出现一次的数字? 考察知识点:异或运算 思路:比如数字 b^b = 0 a^0 = a 因此,可以将数组 ...
- zxing-master core编译
1.下载 Maven: http://maven.apache.org/download.cgi 2.下载完以后,设一下系统变量:MAVE_HOME 3.Path中加入%MAVEN_HOME%\bin ...
- oracle 表空间、用户名 相关语句
一.oracle查询表空间文件所在路径 select * from dba_data_files t where t.tablespace_name='FLW' 二.计算出表空间各相关数据 SELE ...
- dnf脚本的研究
[player number] 2 8 [pvp start area]0 0 0 00 0 0 00 0 0 0[dungeon]62[/dungeon][type] `[normal]`[gre ...
- having与where区别
having后可以跟组函数如avg(sal)而where后不可以有, 如果条件不是必须使用组函数最好还是使用where
- 有关hadoop分布式配置详解
linux配置ssh无密码登录 配置ssh无密码登录,先要安装openssh,如下: yum install openssh-clients 准备两台linux服务器或虚拟机,设置两台linux的ho ...