学懂C++ (一):C++数据类型详解

C++ 数据类型是定义变量所能存储的数据类型的重要组成部分。各种数据类型在 C++ 中具有不同的特性、存储需求和适用场景。以下是对 C++ 数据类型的详细解析,包括基本数据类型、用户定义数据类型、修饰符以及类型转换等内容。

1. 基本数据类型

C++ 中的基本数据类型包括:

1.1 整数类型(Integer Types)

用于表示整数。整数数据类型包括:

  • int:通常为 4 字节(32 位);

    • 范围:-2,147,483,648 到 2,147,483,647(有符号),0 到 4,294,967,295(无符号)。
  • short:通常为 2 字节(16 位);

    • 范围:-32,768 到 32,767(有符号),0 到 65,535(无符号)。
  • long:通常为 4 字节(32 位);

    • 范围:-2,147,483,648 到 2,147,483,647(有符号),0 到 4,294,967,295(无符号)。
  • long long:通常为 8 字节(64 位);

    • 范围:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(有符号),0 到 18,446,744,073,709,551,615(无符号)。

1.2 浮点类型(Floating-Point Types)

用于表示带小数的数值。浮点数据类型包括:

  • float:通常为 4 字节(32 位);

    • 范围:大约 1.5 × 10^−45 到 3.4 × 10^38,通常保留 6-7 位有效数字。
  • double:通常为 8 字节(64 位);

    • 范围:大约 5.0 × 10^−324 到 1.7 × 10^308,通常保留 15-16 位有效数字。
  • long double:通常为 8 字节或 16 字节(取决于平台);

    • 范围:精度比 double 高,具体实现依赖于编译器。

1.3 字符类型(Character Types)

字符类型用于存储单个字符。字符数据类型包括:

  • char:通常为 1 字节(8 位);

    • 范围:-128 到 127(有符号),0 到 255(无符号)。用于 ASCII 字符。
  • wchar_t:通常为 2 字节(16 位)或 4 字节(32 位);

    • 用于表示宽字符,适合 Unicode 字符集。

1.4 布尔类型(Boolean Type)

布尔类型用于表示逻辑值。C++ 中的布尔数据类型为:

  • bool:采用 1 字节(8 位);
    • 取值为 truefalse

1.5 枚举类型(Enumeration Types)

枚举类型用于定义一组命名整型常量,提供更具可读性的代码。

enum Color { Red, Green, Blue }; // Red=0, Green=1, Blue=2

1.6 空类型(Void Type)

空类型用于表示无返回值的函数,或者表示某种类型未知的情况。

  • void:无类型,主要用于函数的返回类型。

2. 用户定义数据类型

C++ 提供了几种机制以定义用户自定义的数据类型,包括:

2.1 结构体(Structures)

结构体用于组合不同类型的数据。

struct Person {
    string name;
    int age;
};

2.2 联合体(Unions)

联合体允许在相同的内存位置存储不同的数据类型。

union Data {
    int intValue;
    float floatValue;
    char charValue;
};

2.3 类(Classes)

类是 C++ 的核心,支持面向对象编程,可以包含数据成员和成员函数。

class Animal {
public:
    string name;
    void speak() {
        cout << "Animal speaks" << endl;
    }
};

 

2.4 典型数据类型别名(Type Aliases)

可以使用 typedefusing 定义数据类型的别名。

typedef unsigned long ulong;
using uLong = unsigned long;

3. 数据类型修饰符

C++ 允许使用修饰符修改基本数据类型的特性。这些修饰符包括:

  • signed:表示有符号类型(默认为有符号)。
  • unsigned:表示无符号类型(只能表示非负数)。
  • short:表示短整型。
  • long:表示长整型。

示例

unsigned int u = 42;  // 无符号整型
signed char c = 'A';  // 有符号字符型

4. 变量声明与初始化

4.1 变量声明

变量必须在使用之前声明。变量的声明包括数据类型和变量名称。

int age;         // 声明一个整型变量 age
float height;    // 声明一个浮点型变量 height

4.2 变量初始化

可以在声明时或之后对变量进行初始化。

int age = 30;            // 声明并初始化
float height = 1.75f;   // 声明并初始化
char initial = 'A';      // 声明并初始化

4.3 常量

常量用于定义不可更改的值,可以使用 constconstexpr 关键字。

const int MAX_AGE = 100;         // 常量
constexpr double PI = 3.14159;   // 编译时常量

5. 类型转换

C++ 中的类型转换包括隐式转换和显式转换。

5.1 隐式转换

C++ 编译器自动进行的类型转换,例如将 int 转换为 float

int a = 5;
float b = a; // 隐式转换

5.2 显式转换

 使用类型转换运算符进行的转换,C++ 提供了四种主要的类型转换运算符:static_castdynamic_castconst_castreinterpret_cast。下面是这些运算符的详细介绍:

1. static_cast

作用

static_cast 是一种用于进行基本类型转换的安全方式。它允许在不同的类型之间进行转换,而且通常用于转换派生类和基类之间的指针或引用。

用法

  • 转换基本数据类型,例如 intfloat
  • 在类层次结构中,将基类指针转换为派生类指针(在确定该指针实际指向的是派生类实例时)。

示例

int a = 10;
float b = static_cast<float>(a); // int 转 float

class Base {};
class Derived : public Base {};

Base* basePtr = new Derived();
Derived* derivedPtr = static_cast<Derived*>(basePtr); // 基类指针转换为派生类指针

注意事项

  • static_cast 不进行运行时检查,因此转换不安全。如果类型不兼容,结果是未定义的行为。

2. dynamic_cast

作用

dynamic_cast 用于在类层次结构中安全地转换指向基类的指针或引用。它用于多态类型,允许在运行时检查转换是否成功。

用法

  • 将基类指针转换为派生类指针。
  • 用于转换引用时,如果转换失败,将抛出 std::bad_cast 异常。

示例

class Base {
    virtual void foo() {} // 需要至少一个虚函数
};
class Derived : public Base {};

Base* basePtr = new Derived();
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 安全转换

if (derivedPtr) {
    // 转换成功
} else {
    // 转换失败
}

注意事项

  • dynamic_cast 只能用于包含虚函数的类。
  • 如果转换失败,返回 nullptr(对于指针)或抛出异常(对于引用)。

3. const_cast

作用

const_cast 用于添加或移除对象的常量性。它可以将 constvolatile 的修饰符从对象中移除。

用法

  • const 指针或引用中获取非 const 指针或引用。

示例

const int a = 10;
int* b = const_cast<int*>(&a); // 转换 const int* 到 int*

// 请注意,对 b 进行修改是未定义行为
*b = 20; // 不建议,可能导致错误

注意事项

  • 通过 const_cast 修改原始对象的内容是未定义行为,特别是当原对象是 const 时。

4. reinterpret_cast

作用

reinterpret_cast 用于进行低级别的类型转换,允许将指针类型转换为其他任何类型的指针。它是最强大但也是最危险的类型转换。

用法

  • 在不同类型之间进行指针转换,包括不同类型之间的强制转型。

示例

int a = 5;
char* p = reinterpret_cast<char*>(&a); // int* 转换为 char*

// 访问指针 p 的内容
for (size_t i = 0; i < sizeof(a); ++i) {
    std::cout << *(p + i) << " "; // 输出 int 的字节
}

注意事项

  • reinterpret_cast 不执行任何类型安全检查,因此使用时需要非常小心。使用不当可能导致未定义行为。

四种类型转换运算符总结

类型转换运算符用途特点
static_cast基本类型和安全的类层次转换无运行时检查
dynamic_cast安全地进行类层次之间的转换运行时检查,仅适用于包含虚函数的类
const_cast添加或移除常量性用于修改常量对象,但需谨慎
reinterpret_cast低级别指针类型转换无类型安全检查,使用风险高

了解这些类型转换运算符及其适用场景是 C++ 编程的重要部分,有助于提高代码的安全性和可读性。

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值