04、C++数据类型

厨子大约 4 分钟C++C++基础编程程序厨

数据类型是构建程序的基础,它决定了变量在内存中存储的方式和大小,以及可以进行的操作。

C++提供了很多内置数据类型,使开发者可以高效地处理和操作各种数据。

基本数据类型

C++提供了多种基本的内置数据类型,每种类型都有特定的关键字和用途:

  1. 布尔型 (bool)

    1. 用途:表示真或假的状态。
    2. 内存****占用:1个字节。
    3. 取值范围:true 或 false。
  2. 字符型 (char)

    1. 用途:存储单个字符,如字母或数字。
    2. 内存****占用:1个字节。
    3. 取值范围
      • char:-128 到 127(signed char)(-2^7 到 2^7 - 1)
      • unsigned char:0 到 255(0 到 2^8 - 1)
  3. 整型 (int)

    1. 用途:存储整数。
    2. 内存****占用:4个字节(在大多数现代系统上)。
    3. 取值范围
      • int:-2,147,483,648 到 2,147,483,647(signed int)(-2^31 到 2^31 - 1)
      • unsigned int:0 到 4,294,967,295(0 到 2^32 - 1)
  4. 浮点型 (float)

    1. 用途:存储单精度浮点数。
    2. 内存****占用:4个字节。
    3. 取值范围:约 ±3.4 × 10^38,有效数字约7位。
  5. 双浮点型 (double)

    1. 用途:存储双精度浮点数。
    2. 内存****占用:8个字节。
    3. 取值范围:约 ±1.7 × 10^308,有效数字约15位。
  6. 长整型 (long)

    1. 用途:存储较大的整数。
    2. 内存****占用:在32位系统上通常为4个字节,在64位系统上通常为8个字节。
    3. 取值范围
      • long:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(signed long)(-2^63 到 2^63 - 1)
      • unsigned long:0 到 18,446,744,073,709,551,615(0 到 2^64 - 1)

类型修饰符

可以使用类型修饰符来改变基本数据类型的属性:

  • signed:表示有符号类型,可以存储正数、负数和零。默认情况下,intshortlong都是有符号的。
  • unsigned:表示无符号类型,只能存储非负整数。
  • short:表示短整型,通常占用2个字节。
  • long:表示长整型,占用字节数依系统而定(通常为4或8个字节)。
  • long long:表示更长的整型,占用8个字节,比long更明确地表明这是一个更大的整数类型。

类型转换

类型转换是将一个数据类型的值转换为另一种数据类型的值的过程。C++中提供了四种类型转换方式:

  1. static_cast

    1. 用途:在相关类型之间进行转换,如从intfloat

    2. 示例

      • int i = 10;
        float f = static_cast<float>(i);
        
  2. dynamic_cast

    1. 用途:用于将基类指针或引用安全地转换为派生类指针或引用。

    2. 示例

      • class Base {};
        class Derived : public Base {};
        Base* ptr_base = new Derived();
        Derived* ptr_derived = dynamic_cast<Derived*>(ptr_base);
        
  3. const_cast

    1. 用途:去除const限定符。

    2. 示例

      • const int i = 10;
        int r = const_cast<int>(i);
        
  4. reinterpret_cast

    1. 用途:在几乎任意类型之间进行转换,不进行任何类型检查。

    2. 示例

      • int i = 10;
        float f = reinterpret_cast<float&>(i);
        

typedef与using

typedefusing都可以用来为类型定义别名,但它们有一些区别:

  • typedef

    • 用法typedef 原有类型 新类型名;

    • 示例

      • typedef unsigned int uint;
        uint a = 10;
        
    • 限制:作用有限,不支持模板类型别名。

  • using

    • 用法using 新类型名 = 原有类型;

    • 示例

      • using uint = unsigned int;
        uint a = 10;
        
    • 优势:作用更广,支持模板类型别名。

建议C++中更多的使用using,一般都是C语言才使用typedef

enum

C语言的教程中咱详细介绍过,枚举类型是一种用户定义的数据类型,它由一组命名的整数常量组成。枚举类型的变量只能取这些常量中的值。

  • 定义

    • enum Color { RED, GREEN, BLUE };
      Color c = RED;
      
  • 赋值:默认情况下,第一个枚举常量的值为0,后续常量值依次递增1。也可以显式赋值。

    • enum Color { RED = 1, GREEN, BLUE };
      
  • 类型转换:枚举类型的值可以隐式转换为整数,但不能隐式转换为其他类型。

高级类型

  • size_t:表示对象的大小或数组元素的个数,是一种无符号整型。大小与平台相关,但足以存储任何对象的大小。
  • wchar_t:宽字符类型,Windows下比较常用,用于支持多字节字符集(如Unicode)。
  • 位域 (bit-field):允许在结构体中定义占用特定位数的成员,用于节省内存。

综合示例代码

详见:https://godbolt.org/z/fxY711s57open in new window

#include <iostream>
#include <limits>
using namespace std;

enum Color { RED, GREEN, BLUE };
typedef unsigned int uint;

int main() {
    bool flag = true;
    char ch = 'A';
    signed char sch = -10;
    unsigned char uch = 200;
    int i = -1000;
    unsigned int ui = 1000;
    long l = 123456789L;
    unsigned long ul = 1234567890UL;
    long long ll = 9223372036854775807LL;
    unsigned long long ull = 18446744073709551615ULL;
    float f = 3.14f;
    double d = 3.141592653589793;
    long double ld = 3.14159265358979323846L;
    wchar_t wc = L'你';
    size_t size = sizeof(int);

    cout << "Flag: " << flag << endl;
    cout << "Char: " << ch << ", Signed Char: " << sch << ", Unsigned Char: " << uch << endl;
    cout << "Int: " << i << ", Unsigned Int: " << ui << endl;
    cout << "Long: " << l << ", Unsigned Long: " << ul << endl;
    cout << "Long Long: " << ll << ", Unsigned Long Long: " << ull << endl;
    cout << "Float: " << f << ", Double: " << d << ", Long Double: " << ld << endl;
    wcout << "Wide Char: " << wc << endl;
    cout << "Size of int: " << size << " bytes" << endl;

    Color color = RED;
    switch (color) {
        case RED:
            cout << "Color is Red" << endl;
            break;
        case GREEN:
            cout << "Color is Green" << endl;
            break;
        case BLUE:
            cout << "Color is Blue" << endl;
            break;
    }

    uint myUint = 123;
    cout << "Using uint: " << myUint << endl;

    return 0;
}