Skip to content

C++ 数据类型

概述

数据类型是编程语言的基础,它定义了变量可以存储的数据种类以及可以对这些数据执行的操作。C++提供了丰富的内置数据类型,同时也支持用户自定义类型。

🏗️ 数据类型分类

数据类型层次结构

mermaid
graph TD
    A[C++数据类型] --> B[基本类型]
    A --> C[复合类型]
    A --> D[用户定义类型]
    
    B --> B1[整数类型]
    B --> B2[浮点类型]
    B --> B3[字符类型]
    B --> B4[布尔类型]
    B --> B5[空类型]
    
    C --> C1[数组]
    C --> C2[指针]
    C --> C3[引用]
    
    D --> D1[结构体]
    D --> D2[类]
    D --> D3[枚举]

🔢 整数类型

基本整数类型

cpp
#include <iostream>
#include <climits>

int main() {
    // 基本整数类型
    short short_var = 32767;
    int int_var = 2147483647;
    long long_var = 2147483647L;
    long long long_long_var = 9223372036854775807LL;
    
    // 无符号整数类型
    unsigned short ushort_var = 65535;
    unsigned int uint_var = 4294967295U;
    unsigned long ulong_var = 4294967295UL;
    
    // 输出类型大小和范围
    std::cout << "short: " << sizeof(short) << " bytes, 范围: " 
              << SHRT_MIN << " 到 " << SHRT_MAX << std::endl;
    std::cout << "int: " << sizeof(int) << " bytes, 范围: " 
              << INT_MIN << " 到 " << INT_MAX << std::endl;
    
    return 0;
}

整数字面量

cpp
int main() {
    // 不同进制的字面量
    int decimal = 42;           // 十进制
    int octal = 052;            // 八进制(以0开头)
    int hexadecimal = 0x2A;     // 十六进制(以0x开头)
    int binary = 0b101010;      // 二进制(C++14,以0b开头)
    
    // 带后缀的字面量
    unsigned int u_val = 42U;   // unsigned
    long l_val = 42L;           // long
    long long ll_val = 42LL;    // long long
    
    // 数字分隔符(C++14)
    int million = 1'000'000;
    int hex_with_sep = 0xFF'FF'FF'FF;
    
    return 0;
}

🌊 浮点类型

浮点类型基础

cpp
#include <iostream>
#include <iomanip>
#include <cfloat>

int main() {
    // 浮点类型
    float f_val = 3.14159f;           // 单精度浮点数
    double d_val = 3.141592653589793; // 双精度浮点数
    long double ld_val = 3.141592653589793238L; // 扩展精度
    
    // 科学计数法
    double scientific = 1.23e4;       // 1.23 × 10^4 = 12300
    double negative_exp = 1.23e-4;    // 1.23 × 10^-4 = 0.000123
    
    std::cout << std::fixed << std::setprecision(6);
    std::cout << "float: " << sizeof(float) << " bytes, 值: " << f_val << std::endl;
    std::cout << "double: " << sizeof(double) << " bytes, 值: " << d_val << std::endl;
    std::cout << "scientific: " << scientific << std::endl;
    
    return 0;
}

浮点数精度问题

cpp
#include <iostream>
#include <cmath>

bool isEqual(double a, double b, double epsilon = 1e-9) {
    return std::abs(a - b) < epsilon;
}

int main() {
    // 浮点数精度问题
    double a = 0.1 + 0.2;
    double b = 0.3;
    
    std::cout << std::fixed << std::setprecision(20);
    std::cout << "0.1 + 0.2 = " << a << std::endl;
    std::cout << "0.3       = " << b << std::endl;
    std::cout << "直接比较相等? " << (a == b) << std::endl;  // 可能为false!
    std::cout << "使用epsilon比较: " << isEqual(a, b) << std::endl;
    
    return 0;
}

🔤 字符类型

基本字符类型

cpp
#include <iostream>

int main() {
    // 基本字符类型
    char ch = 'A';                    // 8位字符
    wchar_t wch = L'中';              // 宽字符
    char16_t ch16 = u'€';             // UTF-16字符(C++11)
    char32_t ch32 = U'🌟';            // UTF-32字符(C++11)
    
    // 字符的数值表示
    char ascii_A = 65;                // ASCII码65对应'A'
    char hex_A = '\x41';              // 十六进制表示
    
    // 转义字符
    char newline = '\n';              // 换行符
    char tab = '\t';                  // 制表符
    char backslash = '\\';            // 反斜杠
    char quote = '\"';                // 双引号
    
    std::cout << "字符 'A': " << ch << ", ASCII码: " << static_cast<int>(ch) << std::endl;
    std::cout << "char: " << sizeof(char) << " bytes" << std::endl;
    std::cout << "wchar_t: " << sizeof(wchar_t) << " bytes" << std::endl;
    
    return 0;
}

字符串类型

cpp
#include <iostream>
#include <string>

int main() {
    // C风格字符串
    char c_string[] = "Hello, World!";
    const char* c_string_ptr = "Hello, C++!";
    
    // C++字符串类
    std::string cpp_string = "Hello, Modern C++!";
    std::string empty_string;
    std::string initialized_string(10, 'A'); // "AAAAAAAAAA"
    
    // Unicode字符串(C++11)
    std::u16string utf16_string = u"UTF-16 字符串";
    std::u32string utf32_string = U"UTF-32 字符串";
    std::string utf8_string = u8"UTF-8 字符串";
    
    // 原始字符串字面量(C++11)
    std::string raw_string = R"(
        这是一个原始字符串
        可以包含换行和"引号"
        不需要转义 \ 字符
    )";
    
    // 字符串操作
    std::string str1 = "Hello";
    std::string str2 = "World";
    std::string combined = str1 + ", " + str2 + "!";
    
    std::cout << "C++字符串: " << cpp_string << std::endl;
    std::cout << "合并字符串: " << combined << std::endl;
    std::cout << "字符串长度: " << combined.length() << std::endl;
    
    return 0;
}

✅ 布尔类型

布尔类型基础

cpp
#include <iostream>

int main() {
    // 布尔类型
    bool is_true = true;
    bool is_false = false;
    
    // 从其他类型转换为布尔值
    bool from_int = 42;          // true(非零值)
    bool from_zero = 0;          // false(零值)
    bool from_pointer = nullptr; // false(空指针)
    
    std::cout << "bool大小: " << sizeof(bool) << " bytes" << std::endl;
    
    // 布尔值的输出格式
    std::cout << std::boolalpha;  // 以true/false形式输出
    std::cout << "true值: " << is_true << std::endl;
    std::cout << "false值: " << is_false << std::endl;
    
    // 逻辑运算
    bool a = true, b = false;
    std::cout << "a && b: " << (a && b) << std::endl;
    std::cout << "a || b: " << (a || b) << std::endl;
    std::cout << "!a: " << (!a) << std::endl;
    
    return 0;
}

🔀 类型转换

隐式类型转换

cpp
#include <iostream>

int main() {
    // 数值提升
    char c = 'A';
    short s = 100;
    int i = c + s;  // char和short提升为int
    
    // 算术转换
    int int_val = 10;
    double double_val = 3.14;
    double result = int_val + double_val; // int转换为double
    
    std::cout << "char 'A' + short 100 = " << i << std::endl;
    std::cout << "int 10 + double 3.14 = " << result << std::endl;
    
    // 窄化转换(可能丢失精度)
    double big_value = 1000000.7;
    int truncated = big_value;
    std::cout << "double " << big_value << " 转为 int: " << truncated << std::endl;
    
    return 0;
}

显式类型转换

cpp
#include <iostream>

int main() {
    // 1. static_cast - 编译时类型转换
    double d = 3.14159;
    int i = static_cast<int>(d);
    std::cout << "static_cast: double " << d << " -> int " << i << std::endl;
    
    // 2. reinterpret_cast - 重新解释位模式
    int int_val = 65;
    char* char_ptr = reinterpret_cast<char*>(&int_val);
    std::cout << "reinterpret_cast: int " << int_val 
              << " -> char " << *char_ptr << std::endl;
    
    // C风格转换(不推荐)
    double d2 = 2.71828;
    int i2 = (int)d2;
    std::cout << "C风格转换: " << d2 << " -> " << i2 << std::endl;
    
    return 0;
}

📏 sizeof运算符

sizeof运算符详解

cpp
#include <iostream>

struct SimpleStruct {
    char c;     // 1 byte
    int i;      // 4 bytes
    double d;   // 8 bytes
};

int main() {
    // 基本类型大小
    std::cout << "=== 基本类型大小 ===" << std::endl;
    std::cout << "sizeof(char): " << sizeof(char) << std::endl;
    std::cout << "sizeof(int): " << sizeof(int) << std::endl;
    std::cout << "sizeof(double): " << sizeof(double) << std::endl;
    std::cout << "sizeof(bool): " << sizeof(bool) << std::endl;
    
    // 数组大小
    int array[10];
    std::cout << "\n=== 数组大小 ===" << std::endl;
    std::cout << "sizeof(array): " << sizeof(array) << std::endl;
    std::cout << "数组元素个数: " << sizeof(array) / sizeof(array[0]) << std::endl;
    
    // 结构体大小(考虑内存对齐)
    std::cout << "\n=== 结构体大小 ===" << std::endl;
    std::cout << "sizeof(SimpleStruct): " << sizeof(SimpleStruct) << std::endl;
    
    // 指针大小
    std::cout << "\n=== 指针大小 ===" << std::endl;
    std::cout << "sizeof(int*): " << sizeof(int*) << std::endl;
    std::cout << "sizeof(void*): " << sizeof(void*) << std::endl;
    
    return 0;
}

🎯 类型选择指南

何时使用哪种类型

整数类型选择

用途推荐类型说明
一般计数int通常是最高效的整数类型
大数值long long保证至少64位
内存敏感int8_t, int16_t精确控制大小
数组索引size_t无符号,足够大
位操作unsigned避免符号位问题

浮点类型选择

用途推荐类型说明
一般浮点运算double精度和性能的平衡
内存敏感float占用空间少
高精度计算long double最高精度

类型安全最佳实践

cpp
#include <iostream>
#include <limits>

int main() {
    // 1. 使用统一初始化(C++11)
    int value{42};              // 防止窄化转换
    // int narrow{3.14};        // 编译错误,防止精度丢失
    
    // 2. 使用auto进行类型推导
    auto automatic = 42;        // int
    auto precise = 3.14159;     // double
    
    // 3. 检查数值范围
    constexpr int max_safe = std::numeric_limits<int>::max();
    std::cout << "int类型最大值: " << max_safe << std::endl;
    
    // 4. 使用强类型枚举(C++11)
    enum class Color : int { Red = 1, Green = 2, Blue = 3 };
    Color favorite = Color::Blue;
    
    // 5. 显式转换而非隐式转换
    double d = 3.14159;
    int i = static_cast<int>(d);  // 明确意图
    
    return 0;
}

总结

C++数据类型是编程的基础,正确理解和使用数据类型能够:

关键要点

  • 基本类型:整数、浮点、字符、布尔类型各有用途
  • 类型大小:使用sizeof了解类型在内存中的大小
  • 类型转换:优先使用显式转换,注意精度丢失
  • 现代特性:利用C++11及以后的特性提高类型安全

最佳实践

  • 选择合适的类型满足需求
  • 使用统一初始化防止窄化转换
  • 注意浮点数精度问题
  • 避免不必要的类型转换

掌握数据类型是学习C++的重要基础,在接下来的章节中,我们将学习如何声明和使用变量。

本站内容仅供学习和研究使用。