Sizeof的使用总结

1. 基本类型的sizeof:

cout << "char:                    " << sizeof(char) << endl;
cout << "int:                     " << sizeof(int)  << endl;
cout << "unsigned int:            " << sizeof(unsigned int)  << endl;
cout << "long(long int/long long):" << sizeof(long)  << endl;
cout << "short(short int):        " << sizeof(short int)  << endl;
cout << "float:                   " << sizeof(float)  << endl;
cout << "double:                  " << sizeof(int)  << endl;

运行结果:

char:                    1
int:                     4
unsigned int:            4
long(long int/long long):8
short(short int):        2
float:                   4
double:                  4


2. 指针类型的sizeof:

指针类型的sizeof需要先明确它是代表什么,代表指针,则其值为8,因为指针本身占用8字节的长度,如果指向的是类型或对象,则根据指向的类型或对象分析。

const char *p = "123";
cout << "The sizeof of Point:" << sizeof(p) << endl;
cout << "THe sizeof of char :" << sizeof(*p) << endl;

int *p1 = new int(1);
cout << "The sizeof of Point:" << sizeof(p1) << endl;
cout << "The sizeof of int  :" << sizeof(*p1) << endl;

const char **p2 = &p;
cout << "The sizeof of Point:" << sizeof(p2) << endl;
cout << "The sizeof of Point:" << sizeof(*p2) << endl;
cout << "The sizeof of char :" << sizeof(**p2) << endl;

void* (*pf)();
cout << "The sizeof of Function Point:" << sizeof(pf) << endl;

下面为结果,前面都有解释输出的是什么:

The sizeof of Point:8
THe sizeof of char :1
The sizeof of Point:8
The sizeof of int  :4
The sizeof of Point:8
The sizeof of Point:8
The sizeof of char :1
The sizeof of Function Point:8

3. 数组类型的sizeof:

数组类型的sizeof等于它所占的字节,即元素个数*每个元素的sizeof。

const char ch[] = "ABC";
cout << "The sizeof of array:" << sizeof(ch) << endl;

输出的结果是4,解释一下,这是由于"ABC"是"ABC\0"这样的常量数组,所以其sizeof为1*4 = 4.

The sizeof of array:4

4. 结构体的sizeof:

结构体的sizeof比较复杂,其实懂的话也就不难了。我这里也不做那么深入的解释,其实我也不怎么会。

先不看位域结构体以及含有pack的结构体,看普通含有基本类型的结构体先:

struct node
{
	char c;
	double d;
	int a;
}a;

sizeof(a)=24,你可能会很好奇,为什么等于24呢?不应该是1+8+4=13,需要符合4的倍数,所以sizeof(a)=16,不应该是16吗?其实不是这么算的。

首先是char,其占用一个字节,即大小=1,偏移量=1

其次是double,其占用8个字节,而此时偏移量为1,不满足是sizeof(double)的倍数,所以偏移量从8开始,之前空出来的全部补0,这时候,大小=16,偏移量=16

最后是int,其占用4个字节,而此时偏移量为16,满足sizeof(int)的倍数,此时,大小=20,偏移量=20。

最后,整个结构体的大小需要满足最大元素的倍数,即为8的倍数,此时,大小就变成了24。

那么下面的结构体大小是多少呢?

struct node
{
	char c;
	int a;
	double d;
}a;
没错,sizeof(a)=16


之后,再看一个含有pack的结构体:

#pragma pack(push) //保存对齐状态
#pragma pack(4)    //设定为4字节对齐
struct node
{
	int c;
	double d;
	int a;
}a;
#pragma pack(pop)

那么这样sizeof(a)的大小就是16。


最后就是位域结构体:

struct node
{
	char f1:3;
	char f2:4;
	char f3:5;
}a;

这个sizeof(a)是多少呢?答案是2。位域的意义在于提示编译器这个占几位,一字节有8位,而f1占了3位,f2占了4位,f3占了5位,那么就需要两字节来存储这个结构体,答案就是2。


5. 结构体内嵌:

struct A
{
	int a;
	int b;
	int c;
}b;

struct node
{
	char c;
	A a;
}a;

此时sizeof(a)=16,为什么呢?结构体内部嵌套结构体时,内部结构体是按其内部元素的最大长度作为对齐标准的,也就是4。此时a.c之后的偏移量应该是4,4+12=16,16满足4的倍数,所以是16。


6. 内含联合体的结构体:

先看一下下面这个含有联合体的结构体:

struct node
{
	char c;
	union A
	{
		double a;
	};
}a;

这个的大小和下面这个是否相同呢?

struct node
{
	char c;
	union A
	{
		double a;
	}a;
}a;
答案是不一样的,第一个sizeof的大小为1,第二个大小为16,为什么呢!第一个的联合体是没有在结构体内部声明变量的,也就是说他只是一个声明而已,而第二个是又在里面定义的!这就导致了大小的不同。

此外,union里面的元素和struct没啥区别。


7. 内含枚举的结构体:

struct node
{
	char c;
	enum name
	{
		ABC=1,DEF=2,HIJ=3
	};
}a;

上面这个和下面这个是否相同呢?

struct node
{
	char c;
	enum name
	{
		ABC=1,DEF=2,HIJ=3
	}a;
}a;

其实和union是一样的!没有定义枚举的实例就不会占用内存。而且枚举所占用的内存都是4,无论里面有多少东西。


8. 类的sizeof:

这个比上面那些都要复杂,学完之后再来总结。(包括虚函数,虚继承带来的开销)


9. 最后,来一题过去阿里笔试题:

#pragma pack(push)
#pragma pack(2)
class A
{
	int i;
	union U
	{
		char buff[13];
		int i;
	}u;
	void foo(){}
	typedef char* (*f)(void *);
	enum name
	{
		red,green,blue
	}color;
}a;

#pragma pack(pop)

答案是22。

为什么呢?

首先是int,占4个字节。

然后联合体,记住联合体占的内存只与最长的一样,即为13,这里强制以2字节对齐,就是14字节。

下面那些没用,看到枚举,一个枚举无论里面有什么都是4。

所以结果为4+14+4 = 22,满足以2对齐的要求,所以答案是22。


参考网站:

https://blog.csdn.net/freefalcon/article/details/54839

https://www.cnblogs.com/x_wukong/p/5743369.html

https://blog.csdn.net/jollyhope/article/details/1895357

https://blog.csdn.net/michaelrun/article/details/1821529

https://www.cnblogs.com/shrimp-can/p/5171110.html


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值