C++ 数据类型

目录

一、引言

二、基础数据类型:内置的 “原子级” 数据单元

2.1 整型:存储整数的 “容器”

2.2 浮点型:处理小数的 “精密仪器”

2.3 字符型:文本世界的 “最小单元”

2.4 布尔型:逻辑世界的 “开关”

三、复合数据类型:构建复杂数据结构的 “积木”

3.1 数组:同类型数据的 “线性集合”

3.2 指针:内存地址的 “导航仪”

3.3 引用:变量的 “别名”

3.4 结构体(struct):自定义数据的 “集装箱”

3.5 联合体(union):内存复用的 “节省者”

四、类型限定符与修饰符:细化数据的 “属性标签”

五、数据类型转换:不同类型间的 “桥梁”

5.1 隐式转换(自动转换)

5.2 显式转换(强制类型转换)

六、内存管理与数据类型的关系


一、引言

在 C++ 编程中,数据类型是构建程序的基石。它不仅决定了数据在内存中的存储方式和占用空间,还定义了数据可参与的操作。本文将系统梳理 C++ 的各类数据类型,结合实例讲解其特性与使用场景,帮助开发者深入理解数据在程序中的流转逻辑。

二、基础数据类型:内置的 “原子级” 数据单元

基础数据类型是 C++ 内置的、不可再分割的数据类型,直接对应计算机底层的存储单元。

2.1 整型:存储整数的 “容器”

数据类型 关键字 典型大小(32/64 位系统) 取值范围 应用场景
短整型 short 2 字节 -32768 ~ 32767 小范围整数计数
整型 int 4 字节 -2147483648 ~ 2147483647 常规整数运算
长整型 long 4/8 字节 依赖平台(通常≥int) 跨平台兼容的大整数
长整型 long long 8 字节 -9223372036854775808 ~ 9223372036854775807 超大整数存储(如时间戳)
无符号整型 unsigned int 4 字节 0 ~ 4294967295 非负计数、位运算

2.2 浮点型:处理小数的 “精密仪器”

  • 单精度浮点型(float):4 字节,精度约 6-7 位有效数字,适用于图形渲染、科学计算中的近似值。

  • 双精度浮点型(double):8 字节,精度约 15-17 位有效数字,常用于金融计算、工程测量等高精度场景。

  • 长双精度型(long double):8/16 字节(依平台而定),提供更高精度,但需谨慎使用以避免内存浪费。

⚠️ 浮点型存在精度误差,避免直接比较两个浮点数是否相等,建议用差值小于极小值(如 1e-8)判断。

2.3 字符型:文本世界的 “最小单元”

  • char:1 字节,通常用于存储 ASCII 字符(-128~127 或 0~255,取决于是否为有符号)。
  • wchar_t:宽字符类型,2/4 字节,用于存储 Unicode 字符(如中文、日文)。
  • char16_t/char32_t:C++11 新增,分别占 2/4 字节,对应 UTF-16 和 UTF-32 编码。

2.4 布尔型:逻辑世界的 “开关”

  • bool:1 字节,取值true(非 0)或false(0),用于条件判断。

三、复合数据类型:构建复杂数据结构的 “积木”

复合数据类型由基础类型组合而成,用于表示结构化数据。

3.1 数组:同类型数据的 “线性集合”

  • 定义格式类型 数组名[长度],长度必须为常量表达式。
int scores[5] = {90, 85, 92, 78, 88}; // 整型数组
char str[] = "Hello World"; // 字符数组,自动计算长度(含'\0')
  • 特性
    • 内存连续存储,通过索引(从 0 开始)访问元素。
    • 数组名本质是指向首元素的指针(注意与指针的区别)。

3.2 指针:内存地址的 “导航仪”

  • 作用:存储变量的内存地址,用于动态内存管理、函数传参优化等。
int num = 10;
int* ptr = # // 指针ptr指向num的地址
*ptr = 20; // 通过解引用修改num的值(此时num变为20)
  • 关键概念
    • 空指针:int* p = nullptr;(C++11 替代NULL)。
    • 指针运算:支持加减整数(偏移字节数 = 步长 ×sizeof (类型))。

3.3 引用:变量的 “别名”

  • 定义类型& 引用名 = 目标变量;必须初始化,一旦绑定不可更改。

double value = 3.14;
double& ref = value; // ref是value的别名
ref = 6.28; // 修改ref等同于修改value
  • 应用场景
    • 函数参数传递(避免拷贝开销,见示例):
    void swap(int& a, int& b) { // 通过引用直接修改实参
        int temp = a;
        a = b;
        b = temp;
    }
    

3.4 结构体(struct):自定义数据的 “集装箱”

  • 作用:将不同类型的数据组合为一个整体,用于表示复杂对象。
struct Student { // 定义结构体类型
    int id;
    string name;
    float score;
};

Student tom = {1001, "Tom", 89.5}; // 创建结构体变量
cout << tom.name << "的成绩是:" << tom.score; // 访问成员
  • 进阶特性:结构体可包含函数成员(C++ 中与 class 的区别主要在于默认访问权限)。

3.5 联合体(union):内存复用的 “节省者”

  • 特点:所有成员共享同一段内存,同一时刻只能存储一个成员的值。
union Data {
    int i;
    float f;
    char c;
}; // 大小为最大成员的字节数(如float占4字节,则union占4字节)

Data d;
d.i = 100; // 此时d.f和d.c的值无意义
d.f = 3.14f; // 覆盖之前的i值
  • 应用场景:嵌入式系统中节省内存,或解析不同格式的二进制数据。

四、类型限定符与修饰符:细化数据的 “属性标签”

  • const:声明常量,值不可修改(用于保护数据或提高代码可读性)。
    const int MAX_SIZE = 100; // 常量表达式
    const char* msg = "Hello"; // 指针指向的字符串不可修改
    
  • volatile:告诉编译器变量可能被意外修改(如寄存器值、多线程共享数据),禁止优化。
  • static:静态存储类,修饰全局变量时延长生命周期,修饰局部变量时保持值不被销毁。
  • auto(C++11):类型自动推导,简化变量声明(如auto it = vec.begin();)。
  • decltype(C++11):推导表达式的类型,用于模板编程和泛型代码。

五、数据类型转换:不同类型间的 “桥梁”

5.1 隐式转换(自动转换)

  • 规则:小范围类型→大范围类型(如intdouble),非 const→const。
int a = 10;
double b = a; // 隐式转换,a的值转为10.0赋给b

5.2 显式转换(强制类型转换)

  • C 风格转换(类型)表达式(简单但不安全)。
  • C++ 风格转换
    • static_cast<类型>(表达式):用于有意义的转换(如intfloat)。
    • dynamic_cast<类型>(表达式):用于多态类型的安全向下转型(需 RTTI 支持)。
    • const_cast<类型>(表达式):去除const限定符(危险操作,需谨慎)。
    • reinterpret_cast<类型>(表达式):重新解释内存位模式(如指针与整数互转)。

示例

int x = 3;
float y = static_cast(x) + 0.5f; // 显式转换为float计算

六、内存管理与数据类型的关系

  • 栈内存:基础类型和复合类型的局部变量通常存储于此,由编译器自动分配 / 释放。
  • 堆内存:通过new/delete动态分配的内存(如int* p = new int(10);),需手动管理生命周期。
  • 数据对齐:编译器为提高访问效率,会按类型大小对内存地址进行对齐(如double通常对齐 8 字节边界)。

你可能感兴趣的:(C++,c++,开发语言)