当前位置: 首页 > ai >正文

C++ Programming Language —— 第2章:数据类型

目录

1.整型

①含义与作用

②语法格式

 ③语法示例

 ④无符号整型(Unsigned)

⑤例题与应用

例题 1:计算圆的周长

 例题 2:循环计数器

 例题 3:无符号整型的溢出

2.sizeof关键字

①含义

②作用

③语法格式

 ④基本数据类型的sizeof结果

 ⑤数组与指针的sizeof

 ⑥结构体与类的sizeof

⑦函数参数中的数组

 ⑧例题

例题 1:计算数组元素个数

例题 2:结构体的内存布局

 例题 3:动态内存分配

3.实型

①实型的含义与作用

②实型的分类与语法格式

③实型的字面值与精度控制

④实型的运算与注意事项

⑤例题与代码示例

例 1:计算圆的面积

例 2:温度转换(华氏→摄氏)

 例 3:高精度计算

 ⑥实型的优缺点

4.字符型

①基本字符型:char

②含义

③作用

④语法格式

⑤字符与整数的关系

⑥扩展字符类型

 ⑦字符输入输出

 ⑧例题与应用

例题 1:统计字符串中的字母数

例题 2:大小写转换

 例题 3:判断字符类型

 ⑨注意事项

5.转义字符

①含义

②作用

③语法格式

④例题

例 1:换行符的使用

例 2:制表符的使用

6.字符串类型

①C 风格

(1)含义

(2)作用

(3)语法格式

 (4)注意事项

②C++ 标准库的string类

(1)含义

(2)作用

(3)语法格式

(4)常用成员函数

 (5)例题与应用场景

例题 1:C 风格字符串操作

例题 2:string类的应用

③C 风格字符串与string类的对比

7.布尔类型

①含义与作用

②语法格式

③布尔字面量

④布尔表达式

⑤隐式类型转换

⑥示例代码

⑦注意事项

8.数据的输入与输出

①标准输入输出流

②输出操作(使用 cout)

③输入操作(使用 cin)

④格式化输入输出

④文件输入输出

⑤注意事项


1.整型

①含义与作用

  • 含义:整型是用于存储没有小数部分的数值类型
  • 作用
    • 作为程序中的计数器、索引或循环变量。
    • 存储逻辑判断的结果(如0表示假,非零表示真)。
    • 处理数学运算中的整数操作。

②语法格式

C++ 提供了多种整型类型,不同类型的存储空间和取值范围不同:

 ③语法示例

bool isStudent = true;      // 布尔型
char grade = 'A';           // 字符型(存储ASCII值)
short age = 25;             // 短整型
int count = 100;            // 整型
long population = 1000000L; // 长整型(需加后缀L)
long long distance = 9223372036854775807LL; // 超长整型(需加后缀LL)

 ④无符号整型(Unsigned)

  • 作用:存储非负整数,扩大正数的表示范围
  • 语法:在类型前加unsigned关键字。

示例

unsigned int score = 95; // 无符号整型

⑤例题与应用

例题 1:计算圆的周长

#include <iostream>
using namespace std;int main() {const int radius = 5;        // 定义常量半径const double PI = 3.14159;   // 定义常量πdouble circumference = 2 * PI * radius; // 计算周长cout << "圆的周长是: " << circumference << endl;//圆的周长是: 31.4159return 0;
}

 例题 2:循环计数器

#include <iostream>
using namespace std;int main() {for (int i = 0; i < 5; i++) { // 使用int作为计数器cout << "循环次数: " << i << endl;}return 0;
}
//循环次数: 0
//循环次数 : 1
//循环次数 : 2
//循环次数 : 3
//循环次数 : 4

 例题 3:无符号整型的溢出

#include <iostream>
using namespace std;int main() {unsigned int num = 4294967295; // 最大值cout << "初始值: " << num << endl;num = num + 1; // 溢出cout << "溢出后的值: " << num << endl; // 输出0return 0;
}
//初始值: 4294967295
//溢出后的值 : 0

2.sizeof关键字

①含义

在 C++ 里,sizeof是一个编译时一元运算符。借助它,能够计算出一个数据类型或者表达式所占用的内存字节数sizeof会在编译阶段就得出结果,不会在程序运行时执行。

②作用

  • 内存分配:在使用new或者malloc进行动态内存分配时,sizeof能帮忙确定所需的内存大小。
  • 数组操作:可以利用sizeof计算数组的元素数量,不过要注意这种方式不适用于函数参数中的数组。
  • 平台适配:由于不同数据类型在不同平台上占用的字节数可能不同,使用sizeof能保证代码在不同平台上都可以正确运行。
  • 数据结构分析:通过sizeof可以分析结构体或者类的内存布局情况。

③语法格式

sizeof有两种使用语法:

  • 针对数据类型sizeof(type_name)
  • 针对表达式sizeof(expression)或者sizeof expression

下面是一些具体的例子:

sizeof(int);         // 返回int类型占用的字节数
sizeof(double);      // 返回double类型占用的字节数
sizeof(arr);         // 返回数组占用的总字节数
sizeof obj;          // 返回对象占用的字节数(可以省略括号)
#include <iostream>
using namespace std;
int main() {cout << "short 类型所占内存空间为: " << sizeof(short) << endl;
//short 类型所占内存空间为: 2cout << "int 类型所占内存空间为: " << sizeof(int) << endl;
//int 类型所占内存空间为: 4cout << "long 类型所占内存空间为: " << sizeof(long) << endl;
//long 类型所占内存空间为: 4cout << "long long 类型所占内存空间为: " << sizeof(long long) << endl;
//long long 类型所占内存空间为: 8system("pause");return 0;
}

 ④基本数据类型的sizeof结果

在 32 位系统和 64 位系统中,基本数据类型的sizeof结果通常如下(但最终还是要以编译器的实现为准):

sizeof(char)         // 1字节
sizeof(short)        // 2字节
sizeof(int)          // 4字节
sizeof(long)         // 4字节(32位系统)或8字节(64位系统)
sizeof(long long)    // 8字节
sizeof(float)        // 4字节
sizeof(double)       // 8字节
sizeof(bool)         // 1字节

 ⑤数组与指针的sizeof

数组sizeof返回的是整个数组占用的内存字节数。

int arr[10];
sizeof(arr);         // 返回40(假设int占4字节)
sizeof(arr) / sizeof(arr[0]);  // 计算数组元素个数,结果为10

指针sizeof返回的是指针变量本身占用的内存大小,一般在 32 位系统下是 4 字节,在 64 位系统下是 8 字节。

int* ptr = new int[10];
sizeof(ptr);         // 返回4或8(取决于系统)

 ⑥结构体与类的sizeof

结构体和类的sizeof结果可能会受到内存对齐的影响。

struct MyStruct {char c;            // 1字节int i;             // 4字节(通常需要对齐到4字节边界)double d;          // 8字节
};sizeof(MyStruct);      // 通常是16字节(受内存对齐影响)

⑦函数参数中的数组

当数组作为函数参数时,会退化为指针,此时sizeof返回的是指针的大小。

void func(int arr[]) {sizeof(arr);       // 返回4或8(指针大小),而非数组大小
}

 ⑧例题

例题 1:计算数组元素个数

#include <iostream>
using namespace std;int main() {int arr[] = {1, 2, 3, 4, 5};int size = sizeof(arr) / sizeof(arr[0]);cout << "数组元素个数: " << size << endl;  // 输出5return 0;
}

例题 2:结构体的内存布局

#include <iostream>
using namespace std;struct Data {char a;      // 1字节int b;       // 4字节(对齐到4字节边界)short c;     // 2字节
};int main() {cout << "Data大小: " << sizeof(Data) << endl;  // 输出12(受对齐影响)return 0;
}

 例题 3:动态内存分配

#include <iostream>
using namespace std;int main() {int n = 10;int* arr = new int[n];cout << "指针大小: " << sizeof(arr) << endl;  // 输出4或8delete[] arr;return 0;
}

3.实型

①实型的含义与作用

实型用于存储实数(即带有小数点的数值),广泛应用于科学计算、工程模拟、金融计算等需要高精度数值的场景。与整数类型不同,实型可以表示小数部分和极大 / 极小的数值。

②实型的分类与语法格式

C++ 提供了三种基本实型,精度和存储范围逐级递增:

语法格式

float 变量名 = 值;
double 变量名 = 值;
long double 变量名 = 值;

③实型的字面值与精度控制

  • 字面值后缀

    • f 或 F:指定为float类型(如3.14f)。
    • l 或 L:指定为long double类型(如3.1415926535L)。
    • 无后缀:默认为double类型(如3.14)。
  • 精度控制
    使用iomanip头文件中的setprecision()控制输出精度:

#include <iostream>
#include <iomanip>  // 用于精度控制
using namespace std;int main() {double pi = 3.1415926535;cout << fixed << setprecision(4) << pi;  // 输出3.1416(四舍五入)return 0;
}

④实型的运算与注意事项

  • 运算特性
    实型支持基本算术运算(+、-、*、/),但需注意浮点误差。例如:

float a = 0.1f;
float b = 0.2f;
if ((a + b) == 0.3f) {  // 可能不成立!cout << "相等";
} else {cout << "不相等,因为0.1+0.2≈0.300000012";
}

⑤例题与代码示例

例 1:计算圆的面积

#include <iostream>
using namespace std;int main() {double radius = 5.0;double area = 3.14159 * radius * radius;  // 使用double类型保证精度cout << "圆的面积是:" << area << endl;return 0;
}

例 2:温度转换(华氏→摄氏)

#include <iostream>
using namespace std;int main() {float fahrenheit;cout << "请输入华氏温度:";cin >> fahrenheit;float celsius = (fahrenheit - 32) * 5.0f / 9.0f;  // 使用float类型cout << "摄氏温度是:" << celsius << "°C" << endl;return 0;
}

 例 3:高精度计算

#include <iostream>
#include <iomanip>
using namespace std;int main() {long double distance = 9.4607e15;  // 一光年(米)long double time = 365.25 * 24 * 60 * 60;  // 一年的秒数long double speed = distance / time;  // 光速(米/秒)cout << fixed << setprecision(2) << "光速:" << speed << " m/s" << endl;return 0;
}

 ⑥实型的优缺点

  • 优点

    • 可以表示小数和极大 / 极小的数值。
    • 支持科学计数法(如3.14e2表示 314)。
  • 缺点

    • 存在精度限制,可能导致舍入误差。
    • 运算速度比整数慢。

4.字符型

①基本字符型:char

②含义

char 是 C++ 中最基本的字符类型,通常占用 1 字节(8 位) 内存空间,范围为 -128 到 127 或 0 到 255(取决于编译器是否将其视为有符号类型)。

③作用

  • 存储单个字符(如字母、数字、标点符号)。
  • 处理文本数据,如字符串(C 风格字符串以 \0 结尾的 char 数组)。
  • 作为小型整数使用(范围有限)。

④语法格式

char ch = 'A';    // 单引号用于字符字面量
char newline = '\n';  // 转义字符
char num = '5';     // 字符 '5',而非数字 5

⑤字符与整数的关系

字符在内存中以整数形式存储,可以与整数相互转换:

char ch = 'A';     // ASCII 值为 65
int num = ch;      // num = 65
char c = 66;       // c = 'B'(ASCII 66)// 输出字符及其 ASCII 值
std::cout << ch << " 的 ASCII 值是: " << static_cast<int>(ch) << std::endl;

⑥扩展字符类型

C++ 提供了几种扩展字符类型,用于处理更大范围的字符集:

wchar_t:宽字符类型,用于表示 Unicode 字符,通常为 2 或 4 字节

wchar_t wc = L'中';  // 宽字符字面量需加前缀 L

char16_t 和 char32_t:C++11 引入,分别用于 UTF-16 和 UTF-32 编码的 Unicode 字符。

char16_t u16 = u'好';  // UTF-16
char32_t u32 = U'😀';  // UTF-32

 ⑦字符输入输出

输入:使用 cin 或 getchar()

char ch;
std::cin >> ch;       // 输入单个字符(忽略空白字符)
ch = std::getchar();  // 输入单个字符(包括空白字符)

输出:使用 cout 或 putchar()

std::cout << ch;      // 输出字符
std::putchar(ch);     // 输出字符

 ⑧例题与应用

例题 1:统计字符串中的字母数

#include <iostream>
#include <cctype>  // 字符处理函数库
int main() {char str[] = "Hello, World!";int count = 0;for (int i = 0; str[i] != '\0'; i++) {if (std::isalpha(str[i])) {  // 判断是否为字母count++;}}std::cout << "字母数量: " << count << std::endl;  // 输出: 10return 0;
}

例题 2:大小写转换

char ch = 'a';
char upper = std::toupper(ch);  // 'A'
char lower = std::tolower('B'); // 'b'

 例题 3:判断字符类型

char ch = '5';
bool isDigit = std::isdigit(ch);    // true
bool isSpace = std::isspace('\t');  // true

 ⑨注意事项

  1. 单引号与双引号

    • 单引号 ' 用于字符字面量(如 'A')。
    • 双引号 " 用于字符串字面量(如 "A" 是包含 'A' 和 '\0' 的字符数组)。
  2. 有符号与无符号
    char 是否有符号由编译器决定,可显式指定 signed char 或 unsigned char

  3. 字符串处理
    C++ 标准库提供 std::string 类,比 C 风格字符串更安全易用。


5.转义字符

①含义

转义字符是由反斜杠\和特定字符组合而成的字符序列,它的主要作用是在代码里表示一些特殊字符,像换行符、制表符等。

②作用

转义字符主要有以下几个方面的作用:

  1. 表达特殊字符:对于那些无法直接输入的字符,比如换行符、制表符等,就可以用转义字符来表示。
  2. 避免语法冲突:当需要在字符串中使用引号或者反斜杠本身时,转义字符能帮助我们避免与语法产生冲突。
  3. 提升可读性:在代码中合理使用转义字符,能够让一些特殊字符的表达更加清晰易懂。

语法格式

转义字符的语法格式是\后面跟上特定字符,下面是一些常见的转义字符及其含义:

④例题

例 1:换行符的使用

#include <iostream>
using namespace std;int main() {cout << "Hello\nWorld!" << endl;return 0;
}

例 2:制表符的使用

#include <iostream>
using namespace std;int main() {cout << "Name\tAge\tCity" << endl;cout << "John\t25\tNew York" << endl;cout << "Alice\t30\tLos Angeles" << endl;return 0;
}

 


6.字符串类型

①C 风格

(1)含义

C 风格字符串是由字符数组组成,以空字符'\0'结尾,用于表示文本数据。

(2)作用

  • 与 C 语言兼容,可用于传统 C 函数(如printfstrcpy等)。
  • 在性能敏感场景中使用(如嵌入式系统)。

(3)语法格式

// 方式1:字符数组初始化
char str1[] = "Hello";  // 自动添加'\0',长度为6
char str2[10] = "World"; // 指定数组大小,剩余位置补'\0'// 方式2:字符指针
const char* str3 = "C++"; // 指向字符串常量,不可修改内容

 (4)注意事项

  • 数组大小需足够容纳字符串和结尾的'\0'
  • 修改字符串常量(如str3[0] = 'D';)会导致未定义行为。

②C++ 标准库的string

(1)含义

string是 C++ 标准库提供的类,封装了字符串操作,自动管理内存,使用更安全便捷。

(2)作用

  • 替代 C 风格字符串,提供更高级的字符串操作(如拼接、查找、替换等)。
  • 自动处理内存分配,避免缓冲区溢出。

(3)语法格式

#include <string> // 需包含头文件// 初始化
std::string s1 = "Hello";      // 直接赋值
std::string s2("World");       // 构造函数初始化
std::string s3 = s1 + " " + s2; // 字符串拼接

(4)常用成员函数

s.length();    // 返回字符串长度
s.empty();     // 判断是否为空
s.substr(1, 3); // 截取子串(从索引1开始,长度3)
s.find("ll");  // 查找子串,返回首次出现的索引
s.replace(0, 2, "Hi"); // 替换部分内容
s += "!";      // 追加字符串

 (5)例题与应用场景

例题 1:C 风格字符串操作

题目:编写函数计算字符串长度(不使用strlen)。

#include <iostream>
int customStrlen(const char* str) {int len = 0;while (str[len] != '\0') {len++;}return len;
}int main() {char str[] = "Example";std::cout << "Length: " << customStrlen(str) << std::endl; // 输出:7return 0;
}
例题 2:string类的应用

题目:反转字符串并统计元音字母数量。

#include <iostream>
#include <string>
#include <algorithm> // 用于std::reverseint countVowels(const std::string& str) {int count = 0;for (char c : str) {c = std::tolower(c);if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {count++;}}return count;
}int main() {std::string s = "Hello World";std::reverse(s.begin(), s.end()); // 反转字符串std::cout << "Reversed: " << s << std::endl; // 输出:dlroW olleHstd::cout << "Vowels: " << countVowels(s) << std::endl; // 输出:3return 0;
}

③C 风格字符串与string类的对比

 


7.布尔类型

①含义与作用

  • 含义:布尔类型主要用于表达逻辑上的真与假,是逻辑运算的基础数据类型
  • 作用:在条件判断、循环控制以及逻辑运算中,布尔类型发挥着关键作用,能够帮助程序依据不同条件来执行相应操作。

②语法格式

  • 声明变量:采用bool 变量名;的形式来声明布尔变量。
  • 赋值操作:可以将布尔字面量true或者false赋值给布尔变量,也能通过布尔表达式的计算结果来赋值。

③布尔字面量

  • true:代表逻辑真。
  • false:代表逻辑假。

④布尔表达式

借助关系运算符(如==><等)和逻辑运算符(如&&||!),可以构建出布尔表达式,其计算结果为布尔值。

  • 关系运算符示例5 > 3的结果是true5 == 3的结果是false
  • 逻辑运算符示例(5 > 3) && (4 < 2)的结果是false

⑤隐式类型转换

  • 数值转布尔:在进行布尔运算时,非零值会被转换为true,而零值会被转换为false
  • 布尔转数值:在需要数值的上下文中,true会被转换为整数1false会被转换为整数0

⑥示例代码

下面通过几个例子,展示布尔类型在实际编程中的常见用法:

#include <iostream>
using namespace std;int main() {// 声明并初始化布尔变量bool isStudent = true;bool hasLicense = false;// 关系表达式返回布尔值bool isGreater = (10 > 5);  // truebool isEqual = (10 == 5);   // false// 逻辑表达式bool isValid = (isStudent && hasLicense);  // falsebool isInvalid = !(isStudent || hasLicense);  // false// 条件语句中的布尔值if (isStudent) {cout << "该用户是学生" << endl;}// 布尔值与整数的隐式转换int result = true + 5;  // true 转换为 1,结果为 6cout << "true + 5 = " << result << endl;// 布尔值作为函数返回值bool isEven(int num) {return (num % 2 == 0);}cout << "4 是偶数: " << (isEven(4) ? "true" : "false") << endl;return 0;
}

输出结果

该用户是学生

true + 5 = 6

4 是偶数: true 

⑦注意事项

  • 不要把布尔值true和整数1、布尔值false和整数0完全等同起来。尽管它们之间可以进行隐式转换,但在语义上是有差别的。
  • 在条件判断中,要避免写出类似if (isStudent == true)这样冗余的代码,直接使用if (isStudent)就可以了。

8.数据的输入与输出

①标准输入输出流

C++ 的标准输入输出流主要依赖于以下对象:

  • cin:标准输入流对象,用于从键盘读取数据。
  • cout:标准输出流对象,用于向屏幕输出数据。
  • cerr:标准错误流对象,用于输出错误信息。
  • clog:标准日志流对象,用于输出日志信息。

输出操作(使用 cout)

含义:将数据从程序传输到标准输出设备(通常是屏幕)。
作用:显示程序运行结果、提示信息等。
语法格式

cout << 表达式1 << 表达式2 << ... << 表达式n;

其中<<是流插入运算符,用于将右侧的表达式值插入到输出流中。

例题 1:输出变量和文本

#include <iostream>
using namespace std;int main() {int age = 25;string name = "Alice";cout << "My name is " << name << ", and I am " << age << " years old." << endl;return 0;
}

输出结果

My name is Alice, and I am 25 years old. 

输入操作(使用 cin)

含义:从标准输入设备(通常是键盘)读取数据到程序中。
作用:获取用户输入,使程序具有交互性。
语法格式

cin >> 变量1 >> 变量2 >> ... >> 变量n;

 例题 2:读取用户输入并计算

#include <iostream>
using namespace std;int main() {int a, b;cout << "Enter two integers: ";cin >> a >> b;int sum = a + b;cout << "The sum is: " << sum << endl;return 0;
}

运行示例

Enter two integers: 10 25

The sum is: 35 

格式化输入输出

C++ 提供了多种方式来格式化输入输出:

  1. 使用流操纵符:如setw(设置字段宽度)、setprecision(设置浮点数精度)等,需包含<iomanip>头文件。
  2. 使用成员函数:如width()precision()等。

例题 3:格式化输出示例

#include <iostream>
#include <iomanip>
using namespace std;int main() {double pi = 3.1415926535;cout << fixed << setprecision(4);  // 设置固定小数位输出,精度为4cout << "Pi is approximately: " << pi << endl;int number = 42;cout << "Number in hexadecimal: " << hex << number << endl;cout << setw(10) << "Left" << setw(10) << "Right" << endl;  // 设置字段宽度return 0;
}

输出结果

Pi is approximately: 3.1416

Number in hexadecimal: 2a

Left        Right 

文件输入输出

除了标准输入输出,C++ 还支持文件的读写操作,主要通过以下类实现:

  • ifstream:用于从文件读取数据(输入文件流)。
  • ofstream:用于向文件写入数据(输出文件流)。
  • fstream:用于读写文件(文件流)。

例题 4:文件读写示例

#include <iostream>
#include <fstream>
using namespace std;int main() {// 写入文件ofstream outFile("data.txt");if (outFile.is_open()) {outFile << "Hello, File I/O!" << endl;outFile << 12345 << endl;outFile.close();} else {cerr << "Unable to open file for writing!" << endl;return 1;}// 读取文件ifstream inFile("data.txt");string line;int number;if (inFile.is_open()) {getline(inFile, line);  // 读取一行文本inFile >> number;       // 读取一个整数cout << "Read from file: " << line << endl;cout << "Number: " << number << endl;inFile.close();} else {cerr << "Unable to open file for reading!" << endl;return 1;}return 0;
}

输出结果

Read from file: Hello, File I/O!

Number: 12345 

⑤注意事项

  1. 类型匹配:输入时要确保变量类型与输入数据类型匹配,否则可能导致输入失败。
  2. 输入缓冲区cin读取数据后,换行符可能留在缓冲区,影响后续输入。可使用cin.ignore()清除缓冲区。
  3. 文件操作:打开文件后要检查是否成功打开,并在使用完毕后关闭文件。
  4. 错误处理:可通过cin.fail()检查输入是否失败,通过ifstream/ofstream的状态检查文件操作是否成功。
http://www.xdnf.cn/news/14566.html

相关文章:

  • C#.NET HttpClient 使用教程
  • 【Dicom标准】dicom数据中pixelData显示处理流程详细介绍
  • Linux 服务器运维:磁盘管理与网络配置
  • 一个免费的视频、音频、文本、图片多媒体处理工具
  • ICM-20948 Wake on Motion功能开发全过程(8)
  • Python 的内置函数 hash
  • python模块常用语法sys、traceback、QApplication
  • 操作系统内核态和用户态--2-系统调用是什么?
  • 决策树:化繁为简的智能决策利器
  • GO语言---数组
  • 【Docker基础】Docker镜像管理:docker rmi、prune详解
  • 经典:在浏览器地址栏输入信息到最终看到网页的全过程,涉及网络协议以及前后端技术
  • Vue状态管理实践:使用Vuex进行前端状态管理
  • FVISION 未来视界工作室:AI驱动的创新与智能外包平台
  • TodoList 案例(Vue3): 使用Composition API
  • Snapchat矩阵运营新策略:亚矩阵云手机打造高效社交网络
  • 基于SpringBoot+Uniapp的活动中心预约小程序(协同过滤算法、腾讯地图、二维码识别)
  • 【论文笔记】【强化微调】TinyLLaVA-Video-R1:小参数模型也能视频推理
  • SQLite 数据库操作完整指南
  • Spring Boot邮件发送终极指南:从基础到高级应用
  • AI大模型学习之基础数学:高斯分布-AI大模型概率统计的基石
  • RocketMQ--为什么性能不如Kafka?
  • Mac电脑-Markdown编辑器-Typora
  • springboot垃圾分类网站
  • 浅议 3D 展示技术为线上车展新体验带来的助力​
  • Qt的学习(七)
  • Kubernetes多容器Pod实战
  • 操作系统进程与线程核心知识全览
  • 一个小BUG引发的对Mybatis-Plus的模糊查询的思考
  • C 语言结构体:从基础到内存对齐深度解析