C++数据类型
本文最后更新于 2024-11-25,文章内容可能已经过时。
sizeof
是 C 和 C++ 编程语言中的一个操作符,用于计算数据类型或变量在内存中所占的字节数。它是一个编译时操作符,这意味着它在程序编译时就被计算出来,而不是在运行时。
sizeof
可以应用于基本数据类型(如 int, char, float 等)、数组、结构体、联合体以及指针等。其语法如下:
sizeof(type)
:计算指定类型type
所占用的字节数。sizeof variable
:计算变量variable
所占用的字节数。sizeof(array)
:对于数组,sizeof
返回整个数组所占用的字节数。sizeof(structure)
或sizeof(union)
:对于结构体或联合体,sizeof
返回它们所占用的最大字节数(注意,由于对齐的原因,实际占用的字节数可能会大于各成员所需字节数之和)。
#include <iostream>
using namespace std;
int main() {
long long money = 100;
cout << "long long变量在内存中所占的字节数:" << sizeof(long long) << endl;
cout << "long long变量在内存中所占的字节数:" << sizeof(money) << endl;
return 0;
}
//long long变量在内存中所占的字节数:8
//long long变量在内存中所占的字节数:8
一、基本数据类型
Ⅰ、整型
char
:通常用于存储字符,但在技术上它是一个整数类型。int
:用于存储整数。short int
:短整型,占用空间比int
小。long int
:长整型,占用空间比int
大。long long int
:更长的整型,占用的空间比long int
更大。
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | (-2^15 ~ 2^15-1) |
int(整型) | 4字节 | (-2^31 ~ 2^31-1) |
long(长整形) | Windows为4字节, Linux为4字节(32位), 8字节(64位) | (-2^31 ~ 2^31-1) |
long long(长长整形) | 8字节 | (-2^63 ~ 2^63-1) |
Ⅱ、浮点型
float
:单精度浮点数。double
:双精度浮点数,比float
精度更高。long double
:扩展精度浮点数,比double
精度更高。
Ⅲ、布尔型
bool
:用于表示真(true
)或假(false
)。
Ⅳ、空类型
void
:表示没有类型,通常用于函数返回值,当函数不返回任何值时使用。
二、派生数据类型
Ⅰ、指针
- 例如:
int*
表示指向int
类型的指针。
Ⅱ、数组
- 例如:
int arr[10]
表示包含10个整数的数组。
Ⅲ、结构体和联合体
- 结构体允许将不同类型的数据组合在一起。
- 联合体类似于结构体,但是所有成员共享同一块内存位置。
Ⅳ、枚举
- 例如:
enum Color {RED, GREEN, BLUE};
定义了一个颜色枚举。
三、复合数据类型
- 类和对象
- 类是用户定义的数据类型,用于封装数据和操作这些数据的方法。
- 对象是类的实例。
四、类型修饰符
- signed 和 unsigned:
- 可以用来指定整数类型是否包含负数。
- 例如:
unsigned int
表示非负整数。
- 例如:
- 可以用来指定整数类型是否包含负数。
- short 和 long:
- 用于改变整数类型的大小。
- 例如:
short int
和long int
。
- 例如:
- 用于改变整数类型的大小。
五、高级数据类型和概念
1、自动类型推导
-
auto:从初始化表达式中自动推导变量的类型。
auto x = 42; // x 的类型为 int auto y = 3.14; // y 的类型为 double
-
decltype:从表达式中推导类型。
int x = 42; decltype(x) y = 10; // y 的类型为 int
2、引用类型
-
引用(References):引用是变量的别名,必须在声明时初始化,并且不能重新绑定到另一个变量。
int x = 42; int& ref = x; // ref 是 x 的引用 ref = 10; // x 的值变为 10
3、常量类型
-
const:用于声明常量,表示该变量的值在声明后不能被修改。
const int x = 42; // x 是一个常量
-
constexpr:用于声明编译时常量,可以在编译时计算结果。
constexpr int square(int x) { return x * x; } constexpr int y = square(5); // y 的值在编译时计算为 25
4、可变类型
-
mutable:用于类中的成员变量,即使类的对象被声明为
const
,该成员变量仍然可以被修改。class MyClass { public: mutable int count; void increment() const { ++count; // 即使对象是 const 的,也可以修改 count } };
5、空指针
-
nullptr:表示空指针常量,替代传统的
NULL
或0
。int* ptr = nullptr; // ptr 是一个空指针
6、范围类型
-
std::pair 和 std::tuple:用于组合多个不同类型的值。
std::pair<int, std::string> p(42, "answer"); std::tuple<int, double, char> t(42, 3.14, 'A');
7、智能指针
-
std::unique_ptr、std::shared_ptr 和 std::weak_ptr:用于管理动态分配的内存,提供自动资源管理。
std::unique_ptr<int> ptr1(new int(42)); // 独占所有权 std::shared_ptr<int> ptr2(new int(42)); // 共享所有权 std::weak_ptr<int> ptr3 = ptr2; // 弱引用
8、模板元编程
-
模板(Templates):用于实现泛型编程,可以在编译时生成特定类型的代码。
template <typename T> T max(T a, T b) { return (a > b) ? a : b; }
9、类型别名
-
typedef 和 using:用于为现有类型创建别名。
typedef unsigned int uint; using uint = unsigned int;
10、类型转换
-
static_cast、dynamic_cast、const_cast 和 reinterpret_cast:用于在不同类型之间进行安全或不安全的类型转换。
int x = 42; double y = static_cast<double>(x); // 显式类型转换
#include <iostream> using namespace std; constexpr int square(int x) { return x * x; } int main() { int x = 42; auto y = static_cast<double>(x); // 显式类型转换 cout << square(x) << endl; cout << y << endl; cout << sizeof(x) << endl; cout << sizeof(y) << endl; return 0; }
六、标准库类型
C++ 标准库提供了许多有用的类型和容器
1、字符串
-
std::string
:用于处理文本字符串。std::string str = "Hello, World!";
2、容器
- 序列容器
std::vector
:动态数组。std::list
:双向链表。std::deque
:双端队列。
- 关联容器
std::set
和std::multiset
:集合,元素唯一或可重复。std::map
和std::multimap
:键值对映射,键唯一或可重复。
- 无序关联容器
std::unordered_set
和std::unordered_multiset
:哈希集合,元素唯一或可重复。std::unordered_map
和std::unordered_multimap
:哈希映射,键唯一或可重复。
3、迭代器
-
用于遍历容器中的元素。
std::vector<int> vec = {1, 2, 3, 4, 5}; for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; }
七、算法
C++ 标准库提供了大量的算法,用于处理容器中的数据
1、排序
-
std::sort
:对容器中的元素进行排序。std::vector<int> vec = {5, 3, 4, 1, 2}; std::sort(vec.begin(), vec.end());
2、查找
-
std::find
:在容器中查找某个元素。auto it = std::find(vec.begin(), vec.end(), 3); if (it != vec.end()) { std::cout << "Found: " << *it << std::endl; }
3、变换
-
std::transform
:对容器中的元素应用某个函数。std::vector<int> vec1 = {1, 2, 3, 4, 5}; std::vector<int> vec2(vec1.size()); std::transform(vec1.begin(), vec1.end(), vec2.begin(), [](int x) { return x * 2; });
八、异常处理
C++ 提供了异常处理机制,用于处理程序运行时可能出现的错误
1、抛出异常
-
throw
:用于抛出异常。throw std::runtime_error("An error occurred!");
2、捕获异常
-
try
和catch
:用于捕获并处理异常。try { // 可能会抛出异常的代码 throw std::runtime_error("An error occurred!"); } catch (const std::exception& e) { std::cerr << "Caught exception: " << e.what() << std::endl; }
九、内存管理
C++ 提供了多种内存管理机制,包括动态内存分配和释放
1、动态内存分配
-
new
和delete
:用于动态分配和释放内存。int* ptr = new int(42); delete ptr;
2、智能指针
-
std::unique_ptr
、std::shared_ptr
和std::weak_ptr
:用于自动管理动态分配的内存。std::unique_ptr<int> ptr1(new int(42)); std::shared_ptr<int> ptr2(new int(42)); std::weak_ptr<int> ptr3 = ptr2;
十、多线程(Multithreading)
C++11 引入了多线程支持,使得并发编程变得更加容易
1、线程
-
std::thread
:用于创建和管理线程。#include <thread> void thread_func() { // 线程函数 } int main() { std::thread t(thread_func); t.join(); return 0; }
2、互斥锁(Mutexes)
-
std::mutex
:用于保护共享资源。#include <mutex> std::mutex mtx; void critical_section() { std::lock_guard<std::mutex> lock(mtx); // 临界区代码 }
十一、文件输入输出(File I/O)
C++ 提供了文件输入输出的支持,用于读写文件
1、文件流
std::ifstream
:用于读取文件。std::ofstream
:用于写入文件。std::fstream
:用于读写文件。
#include <fstream>
void read_file(const std::string& filename) {
std::ifstream file(filename);
std::string line;
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
}
十二、模板元编程(Template Metaprogramming)
模板元编程是一种在编译时执行计算的技术,可以生成高效的代码。
1、模板特化
-
用于为特定类型提供不同的实现。
template <typename T> struct MyType { static const bool value = false; }; template <> struct MyType<int> { static const bool value = true; };
2、递归模板
-
用于在编译时进行递归计算。
template <int N> struct Factorial { static const int value = N * Factorial<N-1>::value; }; template <> struct Factorial<0> { static const int value = 1; };
十三、属性
C++11 引入了属性,用于向编译器提供额外的信息,影响编译行为
1、常用的属性
-
[[nodiscard]]
:建议编译器警告未使用的返回值。 -
[[deprecated]]
:标记过时的函数或类型。[[nodiscard]] int important_function() { return 42; } [[deprecated("Use new_function instead")]] void old_function() { // 旧函数实现 }
十四、模块
C++20 引入了模块,用于替代头文件,提高编译效率和代码组织
1、模块单元
-
module
:定义模块。 -
import
:导入模块。// math.ixx export module math; export int add(int a, int b) { return a + b; } // main.cpp import math; int main() { int result = add(2, 3); std::cout << "Result: " << result << std::endl; return 0; }
十五、总结
C++ 设计多种数据类型的主要原因是为了提供灵活性、效率和安全性。
1. 灵活性
- 适应不同的应用场景:不同的应用领域对数据的需求各不相同。例如,处理图像像素时通常需要8位无符号整数(
unsigned char
),而科学计算可能需要高精度的浮点数(double
)。多种数据类型能够更好地满足这些不同的需求。 - 用户自定义类型:通过结构体、类等自定义类型,开发者可以根据具体需求创建复杂的数据结构,提高代码的可读性和可维护性。
2. 效率
- 内存优化:不同数据类型占用的内存大小不同。例如,
char
占用1个字节,而int
通常占用4个字节。合理选择数据类型可以减少内存消耗,提高程序的运行效率。 - 性能优化:不同类型的数据在进行运算时有不同的性能表现。例如,整数运算通常比浮点数运算更快。选择合适的数据类型可以提高计算速度。
3. 安全性
- 类型检查:C++ 编译器会在编译阶段进行严格的类型检查,确保不同类型的数据不会被错误地混用。这有助于减少运行时错误,提高程序的健壮性。
- 避免溢出:不同大小的整数类型(如
int
、long
、long long
)可以帮助开发者更好地管理数值范围,避免因溢出导致的错误。
4. 表达能力
- 语义清晰:不同的数据类型可以更准确地表达数据的含义。例如,使用
bool
类型可以明确表示逻辑值,使用enum
类型可以定义一组相关的常量,使代码更具可读性。 - 代码规范:合理的类型使用可以遵循编码规范,提高代码的质量和一致性。
5. 兼容性和扩展性
- 兼容性:C++ 作为一种广泛使用的编程语言,需要支持各种硬件平台和操作系统。多种数据类型可以更好地适应不同平台的特性。
- 扩展性:随着技术的发展,新的数据类型和需求不断出现。C++ 的类型系统设计允许添加新的数据类型,如
std::string
、std::vector
等标准库中的类型,以及用户自定义的复杂类型。
- 感谢你赐予我前进的力量