sizeof计算大小规则(一看就会)

看了几遍 sizeof 的内容,老是忘记,这里做下笔记,以供复习与参考。
sizeof(a)用来计算a所占字节大小,其中a可以是类型名,也可以是变量,亦或是对象、函数。
1) sizeof (int); //类型
2) sizeof (a); //int a;变量
3) sizeof (a); //class A; A a;对象
4) sizeof(function_name);//计算的是函数返回类型的值
在计算结构体大小时,由于字节对齐的缘故,需要考虑3个准则(后面有示例):
1.计算前,注意首地址——保证结构体的首地址能被最宽的基本类型成员大小所整除(除非给定了首地址,否则默认首地址为0)。
2.计算时,注意成员偏移量——保证每个成员相对首地址的偏移量是该成员大小的整数倍(注意这里的成员是指此时正在计算的成员,而不是最宽基本类型成员)。
3.计算后,注意总体大小——结构体的总大小应该是结构体中最宽基本类型成员大小的整数倍。

另外,需要注意以下3个问题:
1.上述中说的是都是基本类型,即char(1),short(2),float(4),int(4),double(8),对于结构体嵌套的情况,比如:

struct S{
	 char a;
	 float b;
	 int c;
	 double d;
};//S结构体大小为24
struct B{
	int a;
	S b;
	char c;
};

其中结构体B中嵌套了S,而且S的大小比其他基本类型的大小都大,但我们在计算B的大小时只能按照最宽的基本类型计算(这里是double),而不是按照S的大小作为最宽大小。

2.对于某一类型的指针,其自加或自减所得到的新地址为:A.新地址=A.旧地址+sizeof(A)*step。

比如 struct S s;假设s初始地址为0,自加后的新地址为:0+24*1=24。

3.结构体中,如果定义顺序不同,会影响结构体的总体大小,如:——这里是计算示例

struct S1
{
	short a;//2
	int b;//4
	short c;//2
};
//我们按照上面说的三步走
//1.计算前,首地址为最大基本类型的整数倍,一般默认从0开始,0整除4,没毛病。
//2.计算中:保证每个成员相对首地址的偏移量是该成员大小的整数倍:
//计算a时,由于0可以整除2,故a从0开始,占2个字节-[0,2)
//计算b时,参考准则2,由于2不能整除4,需要在a的后面补2个字节,然后b从4开始,占4个字节-[4,8)
//计算c时,由于8可以整除2,因此不需要补齐字节,所以c从8开始,占2个字节-[8,10)
//3.计算后,上述算的的总体大小为10,根据准则3,总体大小应为最大基本类型(这里是int)的整数倍,因此这里需要补2个字节,所以,最后总体大小为12.
struct s2{
	short a;
	short c;
	int b;
}//通过上述方法可算得,s2的大小为8

所以我们在计算结构体大小时,应按照定义顺序计算。

4.变长结构体不能使用sizeof计算

另外需要注意的是sizeof是关键字,不是函数,它是在编译时计算的,所以他只会算实际分配的内存大小,而不管你用了多少(用了多少是你运行之后确定的),也因此它不能计算动态分配的内存大小。反观strlen,他是一个函数,用来计算字符串的长度,遇到‘\0’结束。函数是在运行时起作用的,所以他计算的是实际有多少内存(以’\0’为界)。

另外,可以通过

#pargma push pack(n)

来设置对齐规则

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值