持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
(欢迎大家关注我的微信公众号——控制工程研习,上面会分享很多我学习过程中总结的笔记。)
测试
请先思考一下这个程序的结果(32位的系统):
#include <iostream>
using namespace std;
union test {
double a;
int b;
int c[3];
};
int main()
{
cout << sizeof(test) << endl;
return 0;
}
答案是16。
如果你答错了,就请看下面的解析吧。
重要特性分析
sizeof()求结果值在面试中经常会遇到,所涉及的知识点不多,大家应该好好掌握住。最常见的就是求类或结构体的大小,有时甚至还会有联合体的计算。
我们需要知道sizeof的几个主要特性:
(1)sizeof是一个编译时运算符,而不是函数;
(2)sizeof不能求得void类型的长度,但能求得void类型的指针的长度;
cout << sizeof(void) << endl; // invalid
cout << sizeof(void*) << endl; // valid
(3)sizeof能求得静态分配内存的数组的长度,但不能求得动态分配的内存的大小。
int a[10];
cout << sizeof(a) << endl; // 返回10*sizeof(int)
int * a = new int[10];
cout << sizeof(a) << endl//返回sizeof(int *)
(4)当表达式作为sizeof的操作数时,它返回表达式的计算结果的类型大小,但是它不对表达式求值.
double a;
float b;
cout << sizeof(a+b) << endl; // 返回sizeof(a),这里是由于默认类型转换为double
cout << sizeof(b = a + b) << endl; // 返回sizeof(b),表达式强制转换为了float类型的b
(5)sizeof可以对函数调用求大小,并且求得的大小等于返回类型的大小,但是不执行函数体。
int test_fun()
{
int ret = 1;
cout << "in test_fun()" << endl;
return ret;
}
// ↓ in main function()
cout << sizeof(test_fun()) << endl; // 返回sizeof(int)
(6)sizeof求得的结构体(及其对象)的大小并不等于各个数据成员对象的大小之和。
#include <iostream>
using namespace std;
struct test_str {
char a;
int b;
};
int main()
{
cout << sizeof(test_str) << endl;
return 0;
}
这个运行结果可能并不是sizeof(char)+sizeof(int),这个代码会在不同的编译器下得到不一样的结果。原因就是内存对齐,对齐方式为成员中最大成员的对齐方式。
详细内容可以参考(内存对齐的内容还是很重要的):
所以这个结果就是与成员的顺序 和 内存对齐值有关。
(7)没有成员变量的结构体/类/联合体的内存值为1。
(8)sizeof(联合体)取决于他所有成员中占用空间最大的一个成员的大小。
#include <iostream>
using namespace std;
union test_union {
char a;
int b;
double c;
};
int main()
{
cout << sizeof(test_union) << endl;
return 0;
}
返回结果为sizeof(double)。
练习&测试
这类在面试中问sizeof()值的题只有记住上面这几个重要特性即可。后面有三个示例,可以自己练习一下(对于32位系统)。
示例一:
#include <iostream>
using namespace std;
#pragma pack(4)
struct test {
double a;
int b;
int c[2];
};
int main()
{
cout << sizeof(test) << endl;
return 0;
}
答案:
24
sizeof(double) = 8,sizeof(int) =4。这里内存对齐值是8,所以b占用内存还是8。c数组也占用8。
示例二:
#include <iostream>
using namespace std;
#pragma pack(4)
struct test {
double a;
int b;
int c[2];
};
int main()
{
cout << sizeof(test) << endl;
return 0;
}
答案:
20.
这里使用#pragma pack(4)修改了内存对齐值为4。所以内存情况如下:
示例三(一开始的测试题):
#include <iostream>
using namespace std;
union test {
double a;
int b;
int c[3];
};
int main()
{
cout << sizeof(test) << endl;
return 0;
}
答案:
16.
这里首先需要知道sizeof(union)返回成员中最大内存的值,也就是sizeof(c)了,这里的c数组大小为3,且为int类型,可能有人就计算其为12了。这没有考虑这个数组在这个联合体中内存对齐的问题,其对齐值是8。所以sizeof(c)的结果就是16了。所以这类题要细心。