先看个例子:
#include <QCoreApplication>
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
struct B{
char a;//1
char c;//1
int e;//4
double d;//8 所以1+1+4+8 补 2
};//16
struct P{
struct B w[2]; //32 按结构体中最大的对齐double 8
short b;//2 //
struct B* p;//4 ,为什么是4,看下面的解释
};
std::cout<<sizeof(P);//40 16*2 + 2 +4 补 2
}
struct B* p;的字节为4,为什么呢?C++面试必考内容:是因为所有的指针类型在32位编译器上无论是何种数据类型的指针,它的大小都是4字节,64位编译器上都是8字节。但是容易混淆的是数组名也是指针,那对数组名计算sizeof值是多少呢?也是4吗?要分情况:
1.数组作为形参时,实质传的是首地址,说白了传的一个指针,所以sizeof值为4.例如:
void foo(int a[4]){cout<<sizeof(a)}
//结果为4
2.除1外的其他情况,sizeof计算的数组字节数为数组总元素所占的字节数。比如:int a[4] = {1,2,3,4};
sizeof(a) = 4 * 4 = 16
总之结构体对齐就一个要点,将变量的字节数一直加,加完了超过了最大对齐数时,按照最大对齐数的整数倍进行补齐就好,举个简单例子:
struct A {char a ; int b; double c;}
// 1+4+8 补3 (最大对齐数为8)
struct B{char a; char b; char c;}
//1+1+1 (这个最大对齐数是1吗?当然不是,如果是32位编译器,此时最大对齐数是4,则要补1,是64位的话最大对齐数就是8,则要补5)
测试:
struct C{char a; char b; char c; int d; double e; short f; float g;}
计算:
1.判断最大对齐数:最大对齐数8
2.直接加就对了:1 + 1 +1 + 4+8+2+4 补多少呢?补 3
结果为24
就这么简单。从上面看出,面试重点:存储上来说:结构体里面的元素是不会共享内存的。结构体的总字节数其实是最大字节数的整数倍
接下来说union联合体:
union A{
int b; //4
char c; //1
}
union B{
char d[3]; //3
double e; //8
}
union C{
int f;
double g[4];//32
}
sizeof(A) = 4;
sizeof(B) = 8
sizeof© = 32
此刻应该发现规律了吧。union是取的最大对齐数的字节数作为sizeof值的。有没有想过为什么呢?
因为uinon联合体是共享内存的,所以取最大的为sizeof值。