[toc]

# 什么是内存对齐

编译器将程序中的每个 "数据单元" 安排在字的整数倍的地址指向的内存之中

# 原则

  • 结构体变量的首地址能够被其最宽基本类型成员大小与对齐基数中的较小者所整除
  • 结构体每个成员相对于结构体首地址的偏移量 (offset) 都是该成员大小与对齐基数中的较小者的整数倍,如果有需要编译器会在成员之间加上填充字节 (internal padding)
  • 结构体的总大小为结构体最宽基本类型成员大小与对齐基数中的较小者的整数倍,如有需要编译器会在最末的一个成员之后上加上填充字节 (trailing padding).

# 实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
using namespace std;

struct A{
short var; //2字节
int var1; //8字节(内存对齐原则,填充2字节) 2(short)+2(填充)+4(int) = 8
long var2; //12字节 8+4(long) = 12
char var3; //16字节(内存对齐原则: 填充3个字节),12+1(char)+3(填充) = 16
string s; //48字节 16+32(string) = 48
};

int main(){
short var;
int var1;
long var2;
char var3;
string s;

A ex1;
cout<< sizeof(var) <<endl; //2 short
cout<< sizeof(var1) <<endl; //4 int
cout<< sizeof(var2) <<endl; //4 long
cout<< sizeof(var3) <<endl; //1 char
cout<< sizeof(s) <<endl; //32 string
cout<< sizeof(ex1) <<endl; //48 A


return 0;
}

# 为什么进行内存对齐

主要是硬件方面的问题

  • 某些硬件设备只能存取对齐数据,存取非对齐的数据可能会引发异常
  • 某些硬件设备不能保存在存取非对齐数据的时候的操作是原子操作
  • 相比于存取对齐的数据,存取非对齐的数据要花费更多的时间
  • 某些处理器虽然支持非对齐数据的访问,但会引发对其陷阱
  • 某些硬件设备只支持简单数据指令非对齐存取,不支持复杂数据指令的非对齐存取

# 内存对齐的优点

  • 便于在不同的平台之间进行移植,因为有些硬件平台不能够支持任意地址的数据访问,只能在某些地址处取某些特定的数据,否则会出现异常
  • 提高内存的访问效率,因为 CPU 在读取内存时,是一块一块的读的

# 与内存对齐相符的类型相关

# 选择整数类型

摘自《C++ Primary Plus P38》 int 被设置为对目标计算机而言最为 "自然" 的长度,自然长度 (natural size) 指的是计算机处理起来效率最高的长度。所以最好使用 int 使用大型整形数组时,最好选择 short 如果只需要一个字节,选择 char 也可以

# 整形字面值

即不同进制下的表示

  • 十进制:第一位为 1~9, 比如 93
  • 八进制:第一位是 0, 第二位为 1~7, 比如 042
  • 十六进制:前两位是 0x 或者 0X, 比如 0x42

如果作为常量输入,则从 int,unsigned int,long,unsigned long、long long 或者 unsigned long long 中选择最小可承载对应数作为类型.

Tip: cout 默认情况下输出十进制

# cout 的控制符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream>
using namespace std;
int main(){
int chest = 42;
int waist = 42;
int inseam = 42;

cout<<"Monsieur cuts a striking figure!"<<endl;
cout<<"chest = "<<chest<<"(decimal for 42)" <<endl;
cout<<hex; //更改显示数字的进制方式
cout<<"waist = " <<waist <<" (hexadecimal for 42) " << endl;
cout<<oct;
cout<<"inseam = "<<inseam <<" (octal for 42)" <<endl;
}

# 字符类型

wchar_t: 宽字符,如 Unicode

# 控制台字符串刷新

用’\b’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream>

int main(){
using namespace std;
cout<<"Enter your agent code:______\b\b\b\b\b\b";
long code;
cin>>code;
cout<<"Your entered: "<<code<<"...\n";


return 0;
}


# 数据类型和大小对应关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<iostream> 
#include<string>
#include <limits>
using namespace std;

int main()
{
cout << "type: \t\t" << "************size**************"<< endl;
cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);
cout << "\t最大值:" << (numeric_limits<bool>::max)();
cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;
cout << "char: \t\t" << "所占字节数:" << sizeof(char);
cout << "\t最大值:" << (numeric_limits<char>::max)();
cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl;
cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);
cout << "\t最大值:" << (numeric_limits<signed char>::max)();
cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl;
cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);
cout << "\t最大值:" << (numeric_limits<unsigned char>::max)();
cout << "\t\t最小值:" << (numeric_limits<unsigned char>::min)() << endl;
cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t);
cout << "\t最大值:" << (numeric_limits<wchar_t>::max)();
cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl;
cout << "short: \t\t" << "所占字节数:" << sizeof(short);
cout << "\t最大值:" << (numeric_limits<short>::max)();
cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;
cout << "int: \t\t" << "所占字节数:" << sizeof(int);
cout << "\t最大值:" << (numeric_limits<int>::max)();
cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;
cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned);
cout << "\t最大值:" << (numeric_limits<unsigned>::max)();
cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;
cout << "long: \t\t" << "所占字节数:" << sizeof(long);
cout << "\t最大值:" << (numeric_limits<long>::max)();
cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;
cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);
cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();
cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;
cout << "double: \t" << "所占字节数:" << sizeof(double);
cout << "\t最大值:" << (numeric_limits<double>::max)();
cout << "\t最小值:" << (numeric_limits<double>::min)() << endl;
cout << "long double: \t" << "所占字节数:" << sizeof(long double);
cout << "\t最大值:" << (numeric_limits<long double>::max)();
cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl;
cout << "float: \t\t" << "所占字节数:" << sizeof(float);
cout << "\t最大值:" << (numeric_limits<float>::max)();
cout << "\t最小值:" << (numeric_limits<float>::min)() << endl;
cout << "size_t: \t" << "所占字节数:" << sizeof(size_t);
cout << "\t最大值:" << (numeric_limits<size_t>::max)();
cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl;
cout << "string: \t" << "所占字节数:" << sizeof(string) << endl;
// << "\t最大值:" << (numeric_limits<string>::max)() << "\t最小值:" << (numeric_limits<string>::min)() << endl;
cout << "type: \t\t" << "************size**************"<< endl;
return 0;
}

# enum 类型

1
2
3
4
5
6
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
} 枚举变量;
更新于

请我喝[茶]~( ̄▽ ̄)~*

Solvarg 微信支付

微信支付

Solvarg 支付宝

支付宝

Solvarg 贝宝

贝宝