ps做网站字体用多大的北京新鸿儒做的网站
1. 结构体对齐
要点
- 变量只能存储在他的长度的整数倍地址上
 - 结构体整体对齐跟他的最长的字段整数倍对齐
 
栗子1
struct Example1 {char a;  //1个字节int c;   //4个字节short b; //2个字节
};std::cout << sizeof(Example1 ) << std::endl;   // 12
std::cout << alignof(Example1) << std::endl;   // 4
 
int只能存储的内存序号:0,4,8,12,...
 short只能存储的内存序号:0,2,4,6,...
| 内存序号 | 存储大小 | 
|---|---|
| 0 | char-a | 
| 1 | null | 
| 2 | null | 
| 3 | null | 
| 4 | int-c | 
| 5 | int-c | 
| 6 | int-c | 
| 7 | int-c | 
| 8 | short-b | 
| 9 | short-b | 
现在a、c、b三个变量总共占了10个字节,但是遵循第二点结构体整体对齐跟他的最长的字段的整数倍对齐,所以结构体总体应该是int=4的倍数,也就是4,8,12...
 因此,最后这个结构体的大小是12个字节。对代码进行调试,监视内存窗口可以看到:
 
2. pack
要点
- 变量只能存储在他的min(长度,pack)的整数倍地址上
 - 结构体整体对齐跟他的min(最长的字段,pack)整数倍对齐
 
栗子2
#pragma pack(2)
struct Example2 {char a;  //1个字节int c;   //4个字节short b; //2个字节
};std::cout << sizeof(Example2) << std::endl;   // 8  
std::cout << alignof(Example2) << std::endl;  // 2
 
int原来只能存储的内存序号:0,4,8,12,...->因为min(4, 2) = 2, 现在变成0,2,4,6,...
 short还是只能存储的内存序号:0,2,4,6,...
| 内存序号 | 存储大小 | 
|---|---|
| 0 | char-a | 
| 1 | null | 
| 2 | int-c | 
| 3 | int-c | 
| 4 | int-c | 
| 5 | int-c | 
| 6 | short-b | 
| 7 | short-b | 
现在a、c、b三个变量总共占了8个字节,但是遵循第二点结构体整体对齐跟他的min(最长的字段,pack)整数倍对齐,所以结构体总体应该是pack = 2的倍数,也就是2,4,6,8,...
 因此,最后这个结构体的大小是8个字节。
对阿秀网站栗子上的解释
C++八股基础语法02
要点
- 变量只能存储在他的长度的整数倍地址上
 - 结构体整体对齐跟他的最长的字段整数倍对齐
 
// alignas 生效的情况struct Info {uint8_t a;  //1个字节uint16_t b; //2个字节uint8_t c;  //1个字节
};std::cout << sizeof(Info) << std::endl;   // 6个字节  
std::cout << alignof(Info) << std::endl;  // 2
 
uint8_t只能存储的内存序号:0,1,2,3,...
 uint16_t只能存储的内存序号:0,2,4,6,...
| 内存序号 | 存储大小 | 
|---|---|
| 0 | uint8_t -a | 
| 1 | null | 
| 2 | uint16_t-b | 
| 3 | uint16_t-b | 
| 4 | uint8_t-c | 
null代表内存填充为空
现在a、b、c三个变量总共占了5个字节,但是遵循第二点结构体整体对齐跟他的最长的字段整数倍对齐,所以结构体总体应该是uint16_t大小的倍数,也就是2,4,6,8,...
 因此,最后这个结构体的大小是6个字节。
3. alignas与alignof
c++11以后引入两个关键字 alignas 与 alignof 。其中alignof可以计算出类型的对齐方式,alignas可以指定结构体的对齐方式。
要点
- 变量只能存储在他的长度的整数倍地址上【这一点和普通版没有任何区别】
 - 结构体整体对齐跟他的
max(最长的字段,alignas指定长度)整数倍对齐 
因为alignas只能指定比默认值,也就是结构体最长字段,更大的值。所以对齐大小要么是默认值,要么是比默认值大的值
struct alignas(4) Info2 {uint8_t a;  //1uint16_t b; //2uint8_t c;  //1
};std::cout << sizeof(Info2) << std::endl;   // 8  4 + 4
std::cout << alignof(Info2) << std::endl;  // 4
 
uint8_t只能存储的内存序号:0,1,2,3,...
 uint16_t只能存储的内存序号:0,2,4,6,...
| 内存序号 | 存储大小 | 
|---|---|
| 0 | uint8_t -a | 
| 1 | null | 
| 2 | uint16_t-b | 
| 3 | uint16_t-b | 
| 4 | uint8_t-c | 
现在a、b、c三个变量总共占了5个字节,但是遵循第二点结构体整体对齐跟他的max(最长的字段,alignas指定长度)整数倍对齐,所以结构体总体应该是alignas = 4大小的倍数,也就是4,8,...
 因此,最后这个结构体的大小是8个字节。
后面几个调试的例子运行结果如图:
 


 
