sizeof的理解

news/2024/7/10 6:13:16 标签: class, 编译器, float, c, 优化
cle class="tags" href="/tags/CLASS.html" title=class>class="baidu_pl">
cle_content" class="tags" href="/tags/CLASS.html" title=class>class="article_content clearfix">
content_views" class="tags" href="/tags/CLASS.html" title=class>class="htmledit_views">

有一个求类型所占几字节这个问题经常反复出现࿰c;这里我决定深入的研究一下

 

先简单入手

Sizeof(char) = 1;

Sizeof(bool) =1;

Sizeof(double)= 8;

Sizeof(class="tags" href="/tags/FLOAT.html" title=float>float) =4;

Sizeof(int) =4;

基本类型就这些。这些是不能出错的。

深入一层:

大家都知道class="tags" href="/tags/BianYiQi.html" title=编译器>编译器会对它进行优化

如果我们在win32默认情况下 在vs2005class="tags" href="/tags/BianYiQi.html" title=编译器>编译器。

默认情况下先说两个规程

1.      类型的大小是:类型包含的基本类型中最大的整数倍。如下: sizeof(A)的大小是最大基本类型 double(8)的整数倍。

2.      每个基本类型的偏移地址必须是类型大小的整数倍。例如 int的偏移量必须是 0࿰c;4࿰c;8࿰c;12࿰c;16,….. double 的偏移量必须是0࿰c;8࿰c;16࿰c;24࿰c;32.

一.class="tags" href="/tags/CLASS.html" title=class>class A {

   int a;

   bool b;

   char c;

   double d;

};

 

cellspacing="0" cellpadding="0" border="1">

a

a

a

a

b

c

填充

填充

d

d

d

d

D

d

d

d

sizeof(A)=sizeof(int)+sizeof(bool)+sizeof(char)+2+sizeof(double = 16

二. class="tags" href="/tags/CLASS.html" title=class>class A {

   char c;

   double d;

   int a;

bool b;

};

cellspacing="0" cellpadding="0" border="1">

c

填充

填充

填充

填充

填充

填充

填充

d

d

d

d

d

d

d

d

a

a

a

a

b

填充

填充

填充

sizeof(A)=sizeof(char)+7+sizeof(doulbe)+sizeof(int)+sizeof(bool)+ 3 = 24.  24是double 的整数倍。 所以24是最终结果。

 

再看一个例子:

三. Class A{

 Chara;

Double b;

Int c;

};

cellspacing="0" cellpadding="0" border="1">

a

填充

填充

填充

填充

填充

填充

填充

b

b

b

b

b

b

b

b

c

c

c

c

填充

填充

填充

填充

 

sizeof(A)=sizeof(char)+7+sizeof(doulbe)+sizeof(int) = 20   20不是double 的整数倍࿰c;所以还得填充4个。 所以24是最终结果。

 

我们再深入一下

四. class="tags" href="/tags/CLASS.html" title=class>class CA

{

   char a;

   double  b;

   int c;

};

这个我们好理解。 sizeof(CA)=sizeof(char)+7+sizeof(doulbe)+sizeof(int) + 4 = 24

 

class="tags" href="/tags/CLASS.html" title=class>class CB {

char ch;

   CA ca;

int ib;

}; 

Sizeof(CB)的大小࿰c;就稍微有点麻烦了。在类成员为止的时候必须是类中最大的整数倍。 Sizeof(char)+ sizeof(CA)= 1+24 =25 不是CA当中最大类型的整数倍(最大是8)需要填充7个。所以 为 1+7+24 + sizeof(int) = 36。 36不是8的整数倍࿰c;又需要填充4个࿰c;所以最终结果是40.

cellspacing="0" cellpadding="0" border="1">

Ch

填充

填充

填充

填充

填充

填充

填充

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

Ca的部分

ib

ib

ib

ib

填充

填充

填充

填充

 

五.我们再深入一下

 

union u
{
 double a;
 int b;
};

union u2
{
 char a[13];
 int b;
};

union u3
{
 char a[13];
 char b;
};

cout<<sizeof(u)<<endl; // 8
cout<<sizeof(u2)<<endl; // 16
cout<<sizeof(u3)<<endl; // 13

 

 都知道union的大小取决于它所有的成员中࿰c;占用空间最大的一个成员的大小。所以对于u来说࿰c;大小就是最大的double类型成员a了࿰c;所以sizeof(u)=sizeof(double)=8。但是对于u2和u3࿰c;最大的空间都是char[13]类型的数组࿰c;为什么u3的大小是13࿰c;而u2是16呢?关键在于u2中的成员int b。由于int类型成员的存在࿰c;使u2的对齐方式变成4࿰c;也就是说࿰c;u2的大小必须在4的对界上࿰c;所以占用的空间变成了16(最接近13的对界)。

 

在深入一点点:

union un

{

   int a;

   char b[5];

};

 

class="tags" href="/tags/CLASS.html" title=class>class CA

{

   char a;

   un b;

};

 

Sizeof(un) = 8;

所以 sizeof(CA) = 1+8 = 9 .因为9不是int的整数倍࿰c;需要填充3个。 所以最后是12.

 

再举一个例子:

union un

{

   double a;

   char b[9];

};

 

class="tags" href="/tags/CLASS.html" title=class>class CA

{

   char a;

   un b;

};

 

Sizeof(un) = 16;

所以 sizeof(CA) = 1 + 16 =17。 17不是double的整数倍࿰c;需要填充7个。所以最后是24.

 

在学习 #pragmapack(n)的问题。

这里的n必须是2的幂级࿰c;也就是 n必须是1࿰c;2࿰c;4࿰c;8࿰c;16࿰c;32……࿰c;如果n不是上面的值࿰c;会提示warning࿰c;并且当成默认处理。

 

 

#pragma pack(1) // 就是一字节对齐。这个是比较清楚的。 把所有成员的大小累积起来就没问题了。例子如下

#pragma  pack(1)

class="tags" href="/tags/CLASS.html" title=class>class A {

   int a;

   bool b;

   char c;

   double d;

};

 sizeof(A)=sizeof(int)+sizeof(bool)+sizeof(char)+sizeof(double;

sizeof(A) = 4+ 1+ 1 +8  = 14 . 呵呵࿰c;这是没问题的。

 

好了࿰c;今天就写到这里欢迎大家指正。谢谢。


Ps:需要着重理解的就是两条࿰c;再强调一遍。王雪刚看好了。

1. 每种类型的排列位置的偏移量必须是它的整数倍。 

             例如 class="tags" href="/tags/CLASS.html" title=class>class A{ char a, double b;}; 先对 char a排列࿰c;因为a的大小是1࿰c; 0是1的整数倍࿰c;所以没问题࿰c;第一个位置就是放着char a。(另外说一句0是任何数的整数倍࿰c;类当中的第一个成员都可以直接放置) 放完a之后࿰c;编译量变成了1࿰c;1不是8(double)的整数倍࿰c;所以需要填充7个࿰c;编译量成8的倍数之后࿰c;才可以放置double b;

         加入 class="tags" href="/tags/CLASS.html" title=class>class B { double b, char a;}; 偏移量0是8的整数倍࿰c;所以直接放置double b没问题࿰c;然后编译量变成了8࿰c;8是size(char)的整数倍࿰c;所以直接放置char 啊;


2. 在前面的基础上放好之后࿰c;再判断总和是不是类中最大类型的整数倍。 sizeof(A) = 1 +7 + 8 = 16࿰c; 16是double的整数倍࿰c;所以最终结果就是16;

 sizeof(B) = 8 +1 = 9; 9 不是 double的整数倍所以要填充 填充 到是double的整数倍。9+7= 16; 所以最终解决就是16的整数倍。 


 其实就这两条结论。再复杂的情况也遵守这两条。


还有枚举类型࿰c;枚举类型的大小就是4. 所以枚举比较简单࿰c;易操作。就不再对枚举再详细举例了。

  

 再有就是在类中有Static类型的变量࿰c;这个就不属于我说范围之内了࿰c;这个的看C++基础了࿰c;了解Static类型的成员是由所以的对象共用一份就知道Static类型不包含在类中了。

 

cle>

http://www.niftyadmin.cn/n/1404351.html

相关文章

抉择

当我们面对两个可能的方案&#xff0c;而焦虑的不知何所抉择时&#xff0c;通常表示这两个方案或者一样好&#xff0c;或者一样坏&#xff0c;因而实际上选择哪个都一样&#xff0c;唯一的差别只是先后之序而已。而且&#xff0c;愈是让我们焦虑得厉害的&#xff0c;其实差别越…

wince串口打印函数是如何实现的?

http://www.cnblogs.com/wogoyixikexie/archive/2009/02/11/1388460.html

红色警报 (25 分)

红色警报 (25 分) 战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序&#xff0c;当失去一个城市导致国家被分裂为多个无法连通的区域时&#xff0c;就发出红色警报。注意&#xff1a;若该国本来就不完全连通&#xff0c;是分裂的k个区域&#xff0c;而失去一…

7k7k实习学习到的

1. 编程规范 1.1 引用和指针的区别。 1.1.1 引用不可以为空&#xff0c;定义引用必须初始化&#xff0c;

装了Ce6后VS2005不能连接连线调试的解决

之前VS2005下在线调试AP都很爽的&#xff0c;最近突然发现不行了&#xff0c;出现的问题如下&#xff1a;------ Deploy started: Project: TestSDK, Configuration: Debug SDK_Sirf (ARMV4I) ------这个产品的配置数据已损坏。请与技术支持人员联系。 Deploy: 0 succeeded, 1 …

如何把微软SD卡驱动移植到BSP下

且听风吟 23:11:50对了想问个问题且听风吟 23:14:19如果把SD卡驱动移植到BSP下&#xff0c;编译不会和Public下的原来同样函数名字&#xff0c;变量等冲突&#xff0c;产生错误吗且听风吟 23:14:45在souce下修改&#xff0c;&#xff1f;Mio-CSDN 23:14:51不会的。且听风吟 23:…

C++ 当中的 # 号的作用

//第一种情况作为Stringizing Operator(#)&#xff0c;叫字符串化。#define stringer( x ) printf( #x ) /* 第二种情况作为char Operator(#) 叫做字符化 */#define charger(x) #x/* 第三种情况作为Token-Pasting Operator(##) 叫做连接符 */#define Token(x) (x##x)int _tmai…

悄悄关注 (25 分)

悄悄关注 (25 分) 新浪微博上有个“悄悄关注”&#xff0c;一个用户悄悄关注的人&#xff0c;不出现在这个用户的关注列表上&#xff0c;但系统会推送其悄悄关注的人发表的微博给该用户。现在我们来做一回网络侦探&#xff0c;根据某人的关注列表和其对其他用户的点赞情况&…