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++的重要基础,在接下来的章节中,我们将学习如何声明和使用变量。