一、数据类型
1. 7种基本数据类型
|------|---------|
| 类型 | 关键字 |
| 布尔型 | bool |
| 字符型 | char |
| 整型 | int |
| 浮点型 | float |
| 双浮点型 | double |
| 无类型 | void |
| 宽字符型 | wchar_t |
一些基本类型可以使用一个或多个类型修饰符进行修饰:
- signed:表示变量可以存储负数。对于整型变量来说,signed 可以省略,因为整型变量默认为有符号类型
- unsigned:表示变量不能存储负数。对于整型变量来说,unsigned 可以将变量范围扩大一倍
- short:表示变量的范围比 int 更小。short int 可以缩写为 short
- long:表示变量的范围比 int 更大。long int 可以缩写为 long
- long long:表示变量的范围比 long 更大。C++11 中新增的数据类型修饰符
1.2 数据类型的内存和范围
|------------------|----------|--------------------------------------------------------|
| 类型 | 位 | 范围 |
| char | 1 | -128 到 127 或者 0 到 255 |
| unsigned char | 1 | 0 到 255 |
| signed char | 1 | -128 到 127 |
| short int | 2 | -32768 到 32767 |
| unsigned int | 2 | 0 到 65,535 |
| signed short int | 2 | -32768 到 32767 |
| int | 4 | -2147483648 到 2147483647 |
| unsigned int | 4 | 0 到 4294967295 |
| signed int | 4 | -2147483648 到 2147483647 |
| long int | 8 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
| unsigned int | 8 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
| signed long int | 8 | 0 到 18,446,744,073,709,551,615 |
| float | 4 | 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字) |
| double | 8 | 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字) |
| long double | 16 | 长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字 |
| wchar_t | 2 或 4个字节 | 1 个宽字符 |
1.3 auto 关键字:自动推导类型声明
auto关键字在C++11中引用,用于自动类型推导。当使用auto关键字声明变量时,编译器会根据变量的初始值自动推导出变量的类型。简化代码,避免显式地指定复杂类型
int a= 10;
auto b =a; //类型推导为int类型
unordered_map<int,int> hashtable; //一个int-int的哈希表
auto item = hashtable.find(target - nums[i]); // 用auto关键字之后不需要显式判断item的类型
二、枚举类型
enum class day //限定作用域枚举
{
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday,
};
enum day //非限定作用域枚举
{
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday,
};
三、类型转换
3.1 C++ 类型转换
- static_cast
- dynamic_cast
- const_cast
- reinterpret_cast
(1) 、静态转换static_cast
是将一种数据类型的值强制转换为另一种数据类型的值
int i = 42;
float f = static_cast<float>(i);
(2)、动态转换dynamic_cast
通常用于将一个基类 指针或引用转换为派生类指针或引用
class Base {};
class Derived : public Base {};
Base* ptr_base = new Derived;
Derived* ptr_derived = dynamic_cast<Derived*>(ptr_base); // 将基类指针转换为派生类指针
(3)、常量转换const_cast
用于将 const 类型 的对象转换为非 const 类型的对象
const int i = 10;
int& r = const_cast<int&>(i); // 常量转换,将const int转换为int
(4)、重新解释转换reinterpret_cast
将一个数据类型的值重新解释为另一个数据类型的值,通常用于在不同的数据类型之间进行转换
int i = 10;
float f = reinterpret_cast<float&>(i); // 重新解释将int类型转换为float类型
四、类型限定符
类型限定符提供了变量的额外信息,用于在定义变量或函数时改变它们的默认行为的关键字。
限定符 | 含义 |
---|---|
const | const 定义常量,表示该变量的值不能被修改。 |
volatile | 修饰符 volatile 告诉该变量的值可能会被程序以外的因素改变,如硬件或其他线程 |
restrict | 由 restrict 修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict |
mutable | 表示类中的成员变量可以在 const 成员函数中被修改 |
static | 用于定义静态变量,表示该变量的作用域仅限于当前文件或当前函数内,不会被其他文件或函数访问 |
register | 用于定义寄存器变量,表示该变量被频繁使用,可以存储在CPU的寄存器中,以提高程序的运行效率。 |
-
const 实例
const int NUM = 10; // 定义常量 NUM,其值不可修改
const int* ptr = &NUM; // 定义指向常量的指针,指针所指的值不可修改
int const* ptr2 = &NUM; // 和上面一行等价 -
volatile 实例
volatile int num = 20; // 定义变量 num,其值可能会在未知的时间被改变
-
mutable 实例
class Example {
public:
int get_value() const {
return value_; // const 关键字表示该成员函数不会修改对象中的数据成员
}
void set_value(int value) const {
value_ = value; // mutable 关键字允许在 const 成员函数中修改成员变量
}
private:
mutable int value_;
}; -
static 实例
void example_function() {
static int count = 0; // static 关键字使变量 count 存储在程序生命周期内都存在
count++;
} -
register 实例
void example_function(register int num) {
// register 关键字建议编译器将变量 num 存储在寄存器中
// 以提高程序执行速度
// 但是实际上是否会存储在寄存器中由编译器决定
}
五、C++内存分区
1.全局区 (Global)
全局区是存放全局变量 和静态变量 的内存区域,在程序启动 时自动分配,在程序结束 时自动释放。全局区的内存空间是连续的,由编译器自动管理。全局区的大小也是固定 的,因此只能存放较小的数据
2.常量区 (Const)
常量区是存放常量数据 的内存区域,如字符串常量、全局常量等。常量区内存只读,不可修改 。常量区的内存空间是连续的,由编译器自动管理
3.栈区 (Stack)
栈区是由编译器自动分配和释放的内存区域,存放函数的参数值、局部变量 等。栈区内存的分配和释放速度很快 ,因为它的内存空间是连续 的,且由编译器自动管理。栈区的大小是固定的,一般只能存放较小 的数据。当函数执行完毕后,栈区内存会自动释放,因此不需要手动释放栈区内存
4.堆区 (Heap)
堆区是由程序员手动分配和释放的内存区域,存放程序运行期间动态分配的内存。堆区的内存空间是不连续 的,因此内存分配和释放的速度较慢 ,但是堆区的内存空间较大 ,可以存放较大的数据。堆区内存的分配和释放需要使用 new
和 delete
或 malloc
和 free
等函数手动管理
5.代码区 (Code)
代码区是存放程序的可执行代码的内存区域,由操作系统负责管理。代码区的内存空间是只读的,不可修改
六、注释
C++ 存在三种注释:
//
一般用于单行注释/* ... */
一般用于多行注释#if 0 ... #endif
条件编译注释
块注释用于程序调试,测试时使用 #if 1 来执行测试代码,发布后使用 #if 0 来屏蔽测试代码
#if condition
code1
#else
code2
#endif