C/C++中sizeof()的用法——32位和64位下的sizeof()

本文转自:http://blog.csdn.net/xunfeng13/article/details/51011509

机器平台:X86_64 处理器

操作系统:Red Hat 4.1.2-14

编译器: gcc version 4.1.2 20070626

Size of char is:                                   1

Size of unsigned char is:                     1

Size of signed char is:                  1

Size of int is:                                    4

Size of short is:                                2

Size of long is:                                  8

Size of long int is:                             8

Size of signed int is:                           4

Size of unsigned int is:                       4

Size of unsigned long int is:                8

Size of long long int is:                       8

Size of unsigned long long is:              8

Size of float is:                    4

Size of double is:                 8

Size of long double is:          16

Size of (void *) is:           8

Size of (char *) is:           8

Size of (int *) is:             8

Size of (long *) is:           8

Size of (long long *) is:   8

Size of (float *) is:          8

Size of (double *) is:              8

所有指针都是占8字节

——————————————————————————

机器平台: X86_32 处理器

操作系统:  Windows XP SP2

编译器:    VS2005自带的C++编译器

Size of char is:                            1

Size of unsigned char is:              1

Size of signed char is:           1

Size of int is:                       4

Size of short is:                    2

Size of long is:                     4

Size of long int is:                4

Size of signed int is:             4

Size of unsigned int is:          4

Size of unsigned long int is:         4

Size of long long int is:                8

Size of unsigned long long is:       8

Size of float is:                    4

Size of double is:                 8

Size of long double is:          8

Size of (void *) is:          4

Size of (char *) is:          4

Size of (int *) is:             4

Size of (long *) is:          4

Size of (long long *) is:   4

Size of (float *) is:          4

Size of (double *) is:       4

所有指针都是占4字节

sizeof()功能:计算数据空间的字节数
1.与strlen()比较
      strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为‘\0‘的数组元素。
      而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。
2.指针与静态数组的sizeof操作
      指针均可看为变量类型的一种。所有指针变量的sizeof 操作结果均为4。
注意:int *p; sizeof(p)=4;
                  但sizeof(*p)相当于sizeof(int);      
      对于静态数组,sizeof可直接计算数组大小;
      例:int a[10];char b[]="hello";
              sizeof(a)等于4*10=40;
              sizeof(b)等于6;
 注意:数组做型参时,数组名称当作指针使用!!
               void  fun(char p[])
               {sizeof(p)等于4}

经典问题: 
      double* (*a)[3][6]; 
      cout<<sizeof(a)<<endl; // 4 a为指针
      cout<<sizeof(*a)<<endl; // 72 *a为一个有3*6个指针元素的数组
      cout<<sizeof(**a)<<endl; // 24 **a为数组一维的6个指针
      cout<<sizeof(***a)<<endl; // 4 ***a为一维的第一个指针
      cout<<sizeof(****a)<<endl; // 8 ****a为一个double变量

问题解析:a是一个很奇怪的定义,他表示一个指向double*[3][6]类型数组的指针。既然是指针,所以sizeof(a)就是4。 
      既然a是执行double*[3][6]类型的指针,*a就表示一个double*[3][6]的多维数组类型,因此sizeof(*a)=3*6*sizeof(double*)=72。同样的,**a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof  (double*)=24。***a就表示其中的一个元素,也就是double*了,所以sizeof(***a)=4。至于****a,就是一个double了,所以sizeof(****a)=sizeof(double)=8。 
3.格式的写法
   sizeof操作符,对变量或对象可以不加括号,但若是类型,须加括号。
4.使用sizeof时string的注意事项
   string s="hello";
   sizeof(s)等于string类的大小,sizeof(s.c_str())得到的是与字符串长度。
5.union 与struct的空间计算
   总体上遵循两个原则:
   (1)整体空间是 占用空间最大的成员(的类型)所占字节数的整倍数
   (2)数据对齐原则----内存按结构成员的先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。。。。。
   注意:数组按照单个变量一个一个的摆放,而不是看成整体。如果成员中有自定义的类、结构体,也要注意数组问题。
例:[引用其他帖子的内容]
因为对齐问题使结构体的sizeof变得比较复杂,看下面的例子:(默认对齐方式下)
struct s1
{
char a;
double b;
int c;
char d; 
};

struct s2
{
char a;
char b;
int c;
double d;
};

cout<<sizeof(s1)<<endl; // 24
cout<<sizeof(s2)<<endl; // 16

同样是两个char类型,一个int类型,一个double类型,但是因为对齐问题,导致他们的大小不同。计算结构体大小可以采用元素摆放法,我举例子说明一下:首先,CPU判断结构体的对界,根据上一节的结论,s1和s2的对界都取最大的元素类型,也就是double类型的对界8。然后开始摆放每个元素。
  对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,但是下一个元素d是double类型,要放到8的对界上,离1最接近的地址是8了,所以d被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是4,16可以满足,所以c放在了16,此时下一个空闲地址变成了20,下一个元素d需要对界1,也正好落在对界上,所以d放在了20,结构体在地址21处结束。由于s1的大小需要是8的倍数,所以21-23的空间被保留,s1的大小变成了24。
  对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,下一个元素的对界也是1,所以b摆放在1,下一个空闲地址变成了2;下一个元素c的对界是4,所以取离2最近的地址4摆放c,下一个空闲地址变成了8,下一个元素d的对界是8,所以d摆放在8,所有元素摆放完毕,结构体在15处结束,占用总空间为16,正好是8的倍数。

这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:
struct s1
{
char a[8];
};

struct s2
{
double d;
};

struct s3
{
s1 s;
char a;
};

struct s4
{
s2 s;
char a; 
};
cout<<sizeof(s1)<<endl; // 8
cout<<sizeof(s2)<<endl; // 8
cout<<sizeof(s3)<<endl; // 9
cout<<sizeof(s4)<<endl; // 16;
  s1和s2大小虽然都是8,但是s1的对齐方式是1,s2是8(double),所以在s3和s4中才有这样的差异。
  所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。

补充:不要让double干扰你的位域 
  在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。不过考虑下面的代码:

struct s1 

 int i: 8; 
 int j: 4; 
 double b; 
 int a:3; 
};

struct s2 

 int i; 
 int j; 
 double b; 
 int a; 
};

struct s3 

 int i; 
 int j; 
 int a; 
 double b; 
};

struct s4 

 int i: 8; 
 int j: 4; 
 int a:3; 
 double b; 
};

cout<<sizeof(s1)<<endl; // 24 
cout<<sizeof(s2)<<endl; // 24 
cout<<sizeof(s3)<<endl; // 24 
cout<<sizeof(s4)<<endl; // 16 
  可以看到,有double存在会干涉到位域(sizeof的算法参考上一节),所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。

原文地址:https://www.cnblogs.com/StormWendy/p/8476347.html

时间: 2024-10-09 19:12:33

C/C++中sizeof()的用法——32位和64位下的sizeof()的相关文章

第十七章——配置SQLServer(2)——32位和64位系统中的内存配置

原文:第十七章--配置SQLServer(2)--32位和64位系统中的内存配置 前言: 本文讲述32位和64位系统中的内存配置,在SQLServer 2005/2008中,DBA们往往尝试开启AWE来限制内存.但是,在SQLServer2012以后,这个选项将被弃用,所以不能使用这种方式来控制32位实例的虚拟地址空间.如果你服务器上有很多内存,就只能升级到64位系统.下面是微软给出的内存限制: 虽然2012以后已经弃用AWE,但是了解一下32位系统如何使用AWE(Address Windowi

为什么一个指针在32位系统中占4个字节,在64位系统中占8个字节?

一个指针在64位的计算机上,占8个字节:一个指针在32位的计算机上,占4个字节. 原因如下: 我们都知道cpu是无法直接在硬盘上读取数据的,而是通过内存读取.cpu通过地址总线.数据总线.控制总线三条线对内存中的数据进行传输和操作. 具体流程: 1.cpu通过地址总线,找到该条数据: 2.通过控制总线得知该操作是读操作还是写操作: 3.通过数据总线将该数据读取到cpu或者从cpu写到内存中. 所以, 地址总线的宽度决定了CPU的寻址能力: 数据总线的宽度决定了CPU单次数据传输的传送量,也就是数

c语言sizeof()在32位及64位系统的区别

具体异同如下表所示: 类型 32位系统 64位系统 char 1 1 unsigned char 1 1 signed char 1 1 int 4 4 short 2 2 long 4 8 long int 4 8 signed int 4 4 unsigned int 4 4 unsigned long int 4 8 long long int 8 8 unsigned long long 8 8 float 4 4 double 8 8 long double 8 16 指针类型 4 8

iOS-程序发布-32位和64位系统的兼容

在苹果推出iPhone5S时,64位的应用就走到了眼前.当时就看见苹果官方资料宣布iOS7.x的SDK支持了64位的应用,而且内置的应用都已经是64位. 我记得自己刚刚接触电脑时还有16位的系统,指针的寻址范围还是16位的.当年用TurboC时,还要根据应用的大小选择是tiny模式还是其他.后来很长一段时间使用32位的模型编程,4G是牢牢记住的一个边界条件.而现在,64位走到了眼前. 就如同16位转向32位一样,硬件肯定是最先推出的,SDK也会跟进,然后各种第三方的应用才会逐步跟进,这个过程一般

iOS开发——实战总结&amp;32位升64位的变化

32位升64位的变化 终究还是来了.Apple下发了支持64位的最后通牒: As we announced in October, beginning February 1, 2015 new iOS apps submitted to the App Store must include 64-bit support and be built with the iOS 8 SDK. Beginning June 1, 2015 app updates will also need to fol

判断应用程序是32位还是64位

VC++检测可执行程序DLL.EXE等是32位还是64位 1.首先介绍PE结构 Windows系统下的可执行文件,是基于Microsoft设计的一种新的文件结构,此结构被称之为PE结构.PE的意思是Portable Executable(可移植的执行体),所有Win32执行体都是用PE文件格式,其中包括SYS.DLL.EXE.COM.OCX等.(不管是学习逆向.破解还是安全,了解PE文件格式都是非常必要的.) PE文件的第一个部分是IMAGE_DOS_HEADER,大小为64B,这里面有两个重要

iOS 32位、 64位系统兼容性设置-Xcode创建支持IOS4.3以上版本的应用的方法

方法一: 如果是Xcode 5的话步骤为 点击项目名称->Build Settings->搜索 Architectures 这个里面的原始的值是Standard architectures(armv7,armv7s,arm64) 点击这个值,在下拉列表框中选择 Standard architectures(armv7,armv7s) ,然后保存项目,转到 General里面去就可以看到项目的Target选项里面会从4.3到7.0都有. 如果是Xcode 5.1的话步骤为 点击项目名称->

CentOS 5 上使用yum同时安装32位和64位包的解决方法

在centos上使用yum在线安装软件包的时候,有时候会同时安装32位和64位的包.并且在update的时候也会更新双份. 其实让yum只安装64位的包,只要在 /etc/yum.conf 中加个 exclude 选项: [main] cachedir=/var/cache/yum keepcache=0 plugins=1 ...... exclude=*.i?86 exclude 选项支持正则表达式,*.i?86可以用来过滤掉i386,i686等32bit包. 如果要删除已经安装的32bit

驱动级多开工具,支持32位和64位

标题:[原创]驱动级多开工具,支持32位和64位 作者:绿林科技 时间:2015-5-16 链接:http://blog.csdn.net/o6108/article/details/47790019 作者QQ:1473656864 技术交流群1:177822108 技术交流群2:177822398 通用驱动级多开器,可多开市面上的90%的程序. PS:本来想弄个收费版本的,后来想了想,决定弄成免费.店铺为更新软件版本用的. 软件的About页面有我的QQ和Q群号,请大家把使用过程中遇到的BUG

Photoshop CS6最新官方正式中文破解版(32位、64位)

Photoshop是强大的图形处理软件,在前端开发领域中,主要用于页面的图形设计与网站UI切图. 目前最新版为Adobe Photoshop CS6 在CS6中整合了其Adobe专有的 Mercury图像引擎,通过显卡核心GPU提供了强悍的图片编辑能力. 但是相对于CS5来说,操作上发生了一定程度的变化,所以建议使用时仔细查看说明文档. 此次提供的版本为官方正式中文版,非汉化版.精简版.绿色版.包含Photoshop CS6中的所有组件与素材. 安装时请断开网络,并选择安装试用版.待软件全部安装