C++ 数据类型完全指南
一、基本内置数据类型
1. 整型(Integer Types)
#include <iostream>
#include <climits>
using namespace std;
int main() {
// 基本整型
int a = 42; // 通常为4字节,范围:-2^31 到 2^31-1
short b = 100; // 通常为2字节,范围:-32768 到 32767
long c = 100000L; // 至少4字节
long long d = 10000000000LL; // 至少8字节(C++11)
// 无符号整型
unsigned int ua = 42U;
unsigned short ub = 100;
unsigned long uc = 100000UL;
unsigned long long ud = 10000000000ULL;
// 查看类型大小和范围
cout << "int: " << sizeof(int) << " bytes" << endl;
cout << "int range: " << INT_MIN << " to " << INT_MAX << endl;
cout << "long long: " << sizeof(long long) << " bytes" << endl;
cout << "long long range: " << LLONG_MIN << " to " << LLONG_MAX << endl;
return 0;
}2. 字符型(Character Types)
#include <iostream>
using namespace std;
int main() {
// 基本字符类型
char ch1 = 'A'; // 1字节,ASCII字符
char ch2 = 65; // 可以用数字表示
signed char sch = -100; // 明确指定有符号
unsigned char uch = 200; // 明确指定无符号
// 宽字符类型
wchar_t wch = L'中'; // 宽字符,通常2或4字节
char16_t ch16 = u'A'; // 16位Unicode字符(C++11)
char32_t ch32 = U'😀'; // 32位Unicode字符(C++11)
char8_t ch8 = u8'A'; // UTF-8字符(C++20)
// 字符串字面量
const char* str1 = "Hello"; // C风格字符串
const wchar_t* str2 = L"你好"; // 宽字符串
const char16_t* str3 = u"Hello"; // UTF-16字符串
const char32_t* str4 = U"Hello"; // UTF-32字符串
const char8_t* str5 = u8"Hello"; // UTF-8字符串(C++20)
cout << "char size: " << sizeof(char) << " byte" << endl;
cout << "wchar_t size: " << sizeof(wchar_t) << " bytes" << endl;
return 0;
}3. 浮点型(Floating-Point Types)
#include <iostream>
#include <iomanip>
#include <cfloat>
using namespace std;
int main() {
// 浮点类型
float f = 3.14159f; // 单精度,通常4字节,6-7位有效数字
double d = 3.141592653589793; // 双精度,通常8字节,15-16位有效数字
long double ld = 3.141592653589793238L; // 扩展精度,通常8-16字节
// 科学计数法
float scientific = 1.23e-4f; // 0.000123
double bigNum = 1.5e308; // 非常大的数
// 特殊值
float inf = 1.0f / 0.0f; // 正无穷
float negInf = -1.0f / 0.0f; // 负无穷
float nan = 0.0f / 0.0f; // NaN (Not a Number)
// 精度展示
cout << fixed << setprecision(20);
cout << "float: " << f << endl;
cout << "double: " << d << endl;
cout << "long double: " << ld << endl;
// 范围展示
cout << "float range: " << FLT_MIN << " to " << FLT_MAX << endl;
cout << "double range: " << DBL_MIN << " to " << DBL_MAX << endl;
return 0;
}4. 布尔型(Boolean Type)
#include <iostream>
using namespace std;
int main() {
bool flag1 = true; // true = 1
bool flag2 = false; // false = 0
bool flag3 = 100; // 非零值转换为true
bool flag4 = 0; // 0转换为false
cout << "bool size: " << sizeof(bool) << " byte" << endl;
cout << "true value: " << true << endl; // 输出1
cout << "false value: " << false << endl; // 输出0
cout << boolalpha; // 设置输出为true/false
cout << "true: " << true << ", false: " << false << endl;
return 0;
}5. 空类型(Void Type)
void function() {
// void函数不返回值
}
void* genericPointer; // void指针可以指向任何类型
int x = 10;
genericPointer = &x; // 但需要类型转换才能使用
int* intPtr = static_cast<int*>(genericPointer);二、类型修饰符和限定符
1. const 限定符
#include <iostream>
using namespace std;
int main() {
const int MAX_SIZE = 100; // 常量,不能修改
const double PI = 3.14159;
// 指针和const
int value = 42;
const int* ptr1 = &value; // 指向常量的指针(不能通过ptr1修改值)
int* const ptr2 = &value; // 常量指针(ptr2本身不能改变)
const int* const ptr3 = &value; // 指向常量的常量指针
// const成员函数
class MyClass {
int data;
public:
int getData() const { // const成员函数,不修改对象状态
return data;
}
};
return 0;
}2. volatile 限定符
volatile int hardwareRegister; // 告诉编译器该变量可能被外部改变
volatile bool flag; // 常用于多线程或硬件编程3. mutable 限定符
class CacheClass {
mutable int cacheValue; // 即使在const成员函数中也可修改
mutable bool cacheValid;
public:
int getValue() const {
if (!cacheValid) {
cacheValue = computeValue(); // 可以修改mutable成员
cacheValid = true;
}
return cacheValue;
}
private:
int computeValue() const { return 42; }
};三、派生数据类型
1. 数组(Arrays)
#include <iostream>
#include <array>
using namespace std;
int main() {
// C风格数组
int arr1[5] = {1, 2, 3, 4, 5};
int arr2[] = {1, 2, 3}; // 自动推导大小
int arr3[5] = {1, 2}; // 部分初始化,其余为0
// 多维数组
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 动态数组
int* dynArr = new int[10];
delete[] dynArr;
// std::array (C++11)
array<int, 5> stdArr = {1, 2, 3, 4, 5};
cout << "Size: " << stdArr.size() << endl;
return 0;
}2. 指针(Pointers)
#include <iostream>
#include <memory>
using namespace std;
int main() {
// 基本指针
int x = 42;
int* ptr = &x; // 指向int的指针
int** pptr = &ptr; // 指向指针的指针
// 空指针
int* nullPtr = nullptr; // C++11推荐方式
int* nullPtr2 = NULL; // C风格
int* nullPtr3 = 0; // 另一种方式
// 函数指针
int (*funcPtr)(int, int); // 指向函数的指针
// 智能指针 (C++11)
unique_ptr<int> uptr(new int(42)); // 唯一所有权
shared_ptr<int> sptr = make_shared<int>(42); // 共享所有权
weak_ptr<int> wptr = sptr; // 弱引用
return 0;
}3. 引用(References)
#include <iostream>
using namespace std;
int main() {
int x = 42;
int& ref = x; // 左值引用
const int& cref = x; // 常量引用
// 右值引用 (C++11)
int&& rref = 42; // 可以绑定到临时对象
int&& rref2 = move(x); // 使用move转换为右值
// 引用作为函数参数
auto swap = [](int& a, int& b) {
int temp = a;
a = b;
b = temp;
};
return 0;
}四、用户自定义类型
1. 结构体(Structures)
#include <iostream>
using namespace std;
// 基本结构体
struct Point {
double x;
double y;
// C++中结构体可以有成员函数
double distance() {
return sqrt(x*x + y*y);
}
};
// 带构造函数的结构体
struct Rectangle {
int width;
int height;
Rectangle(int w, int h) : width(w), height(h) {}
int area() const {
return width * height;
}
};
int main() {
Point p1 = {3.0, 4.0};
Point p2{1.0, 2.0}; // C++11统一初始化
Rectangle rect(10, 20);
cout << "Area: " << rect.area() << endl;
return 0;
}2. 联合体(Unions)
#include <iostream>
using namespace std;
union Data {
int i;
float f;
char str[20];
};
// C++11 带标签的联合体
struct TaggedUnion {
enum Type { INT, FLOAT, STRING } type;
union {
int i;
float f;
char str[20];
};
};
int main() {
Data data;
data.i = 10;
cout << data.i << endl;
data.f = 3.14; // 覆盖之前的值
cout << data.f << endl;
return 0;
}3. 枚举(Enumerations)
#include <iostream>
using namespace std;
// C风格枚举
enum Color {
RED, // 0
GREEN, // 1
BLUE // 2
};
// 指定值的枚举
enum Status {
SUCCESS = 0,
ERROR = -1,
PENDING = 100
};
// 强类型枚举 (C++11)
enum class Direction : char {
North = 'N',
South = 'S',
East = 'E',
West = 'W'
};
int main() {
Color c = RED;
Status s = SUCCESS;
Direction d = Direction::North;
// 强类型枚举需要显式转换
char dirChar = static_cast<char>(d);
return 0;
}4. 类(Classes)
#include <iostream>
using namespace std;
class Person {
private:
string name;
int age;
public:
// 构造函数
Person(const string& n, int a) : name(n), age(a) {}
// 成员函数
void display() const {
cout << "Name: " << name << ", Age: " << age << endl;
}
// 析构函数
~Person() {
cout << "Person destroyed" << endl;
}
};五、C++11及之后的新类型
1. auto 类型推导
#include <iostream>
#include <vector>
using namespace std;
int main() {
auto i = 42; // int
auto d = 3.14; // double
auto s = "hello"s; // string (C++14)
vector<int> vec = {1, 2, 3};
auto it = vec.begin(); // vector<int>::iterator
// 函数返回类型推导 (C++14)
auto lambda = [](auto x, auto y) {
return x + y;
};
return 0;
}2. decltype 类型推导
int x = 5;
decltype(x) y = 10; // y是int类型
decltype((x)) z = x; // z是int&类型
// 结合auto使用
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}3. nullptr 类型
#include <iostream>
using namespace std;
void func(int) { cout << "int version" << endl; }
void func(void*) { cout << "pointer version" << endl; }
int main() {
func(0); // 调用int版本
func(NULL); // 可能有歧义
func(nullptr); // 明确调用pointer版本
return 0;
}六、STL容器类型
1. 序列容器
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <array>
#include <forward_list>
using namespace std;
int main() {
// 动态数组
vector<int> vec = {1, 2, 3, 4, 5};
// 双端队列
deque<int> deq = {1, 2, 3};
// 双向链表
list<int> lst = {1, 2, 3};
// 固定大小数组 (C++11)
array<int, 5> arr = {1, 2, 3, 4, 5};
// 单向链表 (C++11)
forward_list<int> flst = {1, 2, 3};
return 0;
}2. 关联容器
#include <iostream>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
using namespace std;
int main() {
// 有序集合
set<int> s = {3, 1, 4, 1, 5};
multiset<int> ms = {1, 1, 2, 2, 3};
// 有序映射
map<string, int> m = {{"one", 1}, {"two", 2}};
multimap<string, int> mm;
// 无序集合 (C++11)
unordered_set<int> us = {1, 2, 3};
unordered_multiset<int> ums;
// 无序映射 (C++11)
unordered_map<string, int> um = {{"a", 1}};
unordered_multimap<string, int> umm;
return 0;
}七、特殊数据类型
1. std::optional (C++17)
#include <iostream>
#include <optional>
using namespace std;
optional<int> divide(int a, int b) {
if (b == 0) return nullopt;
return a / b;
}
int main() {
auto result = divide(10, 2);
if (result.has_value()) {
cout << "Result: " << result.value() << endl;
}
// 或使用value_or提供默认值
cout << divide(10, 0).value_or(-1) << endl;
return 0;
}2. std::variant (C++17)
#include <iostream>
#include <variant>
#include <string>
using namespace std;
int main() {
variant<int, float, string> v;
v = 42;
cout << get<int>(v) << endl;
v = 3.14f;
cout << get<float>(v) << endl;
v = "hello"s;
cout << get<string>(v) << endl;
// 访问器模式
visit([](auto&& arg) {
cout << arg << endl;
}, v);
return 0;
}3. std::any (C++17)
#include <iostream>
#include <any>
using namespace std;
int main() {
any a = 42;
cout << any_cast<int>(a) << endl;
a = 3.14;
cout << any_cast<double>(a) << endl;
a = "hello"s;
cout << any_cast<string>(a) << endl;
// 类型检查
if (a.type() == typeid(string)) {
cout << "a contains a string" << endl;
}
return 0;
}4. std::tuple
#include <iostream>
#include <tuple>
using namespace std;
int main() {
// 创建元组
tuple<int, string, double> t(42, "hello", 3.14);
// 访问元素
cout << get<0>(t) << endl; // 42
cout << get<1>(t) << endl; // hello
cout << get<2>(t) << endl; // 3.14
// 结构化绑定 (C++17)
auto [id, name, score] = t;
cout << id << " " << name << " " << score << endl;
// make_tuple
auto t2 = make_tuple(1, 2.0, "three");
return 0;
}八、类型转换
1. 隐式类型转换
int i = 42;
double d = i; // int到double的隐式转换
char c = 'A';
int ascii = c; // char到int的隐式转换2. 显式类型转换(C++风格)
#include <iostream>
using namespace std;
class Base { virtual void dummy() {} };
class Derived : public Base {};
int main() {
// static_cast - 编译时转换
double d = 3.14;
int i = static_cast<int>(d);
// dynamic_cast - 运行时类型检查(用于多态)
Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base);
// const_cast - 移除const属性
const int ci = 42;
int* pi = const_cast<int*>(&ci);
// reinterpret_cast - 重新解释位模式
int* ip = new int(42);
long addr = reinterpret_cast<long>(ip);
return 0;
}九、类型别名
// typedef传统方式
typedef unsigned long ulong;
typedef int (*FuncPtr)(int, int);
// using现代方式 (C++11)
using ulong = unsigned long;
using FuncPtr = int(*)(int, int);
// 模板别名 (C++11)
template<typename T>
using Vec = std::vector<T>;
Vec<int> numbers = {1, 2, 3, 4, 5};十、类型特性(Type Traits)
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
void checkType() {
cout << "Is integral: " << is_integral<T>::value << endl;
cout << "Is floating point: " << is_floating_point<T>::value << endl;
cout << "Is pointer: " << is_pointer<T>::value << endl;
cout << "Is class: " << is_class<T>::value << endl;
}
int main() {
checkType<int>();
checkType<double>();
checkType<string>();
// 条件类型选择
using Type = conditional<true, int, double>::type; // Type是int
return 0;
}总结
C++提供了丰富的数据类型系统,从基本类型到复杂的模板类型,每种类型都有其特定的用途:
- 基本类型:用于存储简单数据
- 派生类型:通过组合基本类型创建更复杂的数据结构
- 用户定义类型:允许创建符合特定需求的自定义类型
- STL容器:提供高效的数据管理方案
- 现代C++类型:提供更安全、更灵活的类型系统