很久没写C++,决定过一遍runoob,只记录认为需要记录或个人印象不清晰的内容,唤醒一下沉睡的记忆
标准库
核心语言构建块、C++标准库、STL构成
基本语法
三字符组
用于表示键盘上没有的字符,如??=
来表示#
,大部分编译器都不会自动替换三字符组,但g++默认支持三字符组,当程序中需要两个连续的问号时,需要写成 "...?""?..."
或转义为"...?\?..."
数据类型
1 字节(byte) 8 位(bit),
char 占用 1 字节,int 占用 4 字节,long 占用 4 字节,long long 占用 8 字节,float 占用 4 字节,double 占用 8 字节
以上类型的范围只是 C++ 标准规定的最小要求,实际上,许多系统上这些类型可能占用更多的字节,例如,很多现代计算机上 int 通常占用 4 字节,而 long 可能占用 8 字节。
float a;
double b;
a = 77777.7777777;
b = 77777.777777777;
打印出a和b后显示a为77777.781250,b为77777.777778,float 是 32 位浮点数,有 7 位有效数字。double 是 64 位浮点数,有 16 位有效数字。一般编译器规定小数后面最多保留6位数,但这个1250是怎么来的呢?
十进制数 77777.7777777 转换为32位二进制浮点数,在四舍五入后再转换回十进制时,得到了77777.781250
typedef 声明
为一个已有的类型取一个新的名字
typedef type newname;
类型转换
包含四种类型转换:静态转换、动态转换、常量转换、重新解释转换
静态转换
通常用于较相似对象间的转换,不进行任何类型检查
int i = 10;
float f = static_cast<float>(i);
动态转换
通常用于将一个基类指针或引用转换为派生类指针或引用,在运行时进行类型检查
class Base {
};
class Derived : public Base {
};
Base* ptr_base = new Derived;
Derived* ptr_derived = dynamic_cast<Derived*>(ptr_base); // 将基类指针转换为派生类指针
常量转换
用于将 const 类型的对象转换为非 const 类型的对象,只操作 const 属性,不会改变对象类型
const int i = 10;
int& r = const_cast<int&>(i);
重新解释转换
将一个数据类型的值重新解释为另一个数据类型的值,通常用于在不同的数据类型之间进行转换,不进行任何类型检查。静态转换无法处理没有关联性的指针类型转换,也不能在多态类型之间实现转换,这时候就需要重新解释转换出手了。
// 将int类型转换为float类型
int i = 10;
float f = reinterpret_cast<float&>(i);
// 将整数指针转换为字符指针
int* intPtr = new int(42);
char* charPtr = reinterpret_cast<char*>(intPtr);
C++常量
注意把常量定义为大写字母,要有良好的编程习惯
cont int LENGTH = 10;
不应该把布尔值 true 和 false 看成 1 和 0 ,应只看成 真 和 假
C++修饰符
有符号整数和无符号整数修饰符有很大的差别,而不仅仅是体现在符号上。
#include <iostream>
using namespace std;
int main()
{
short int i;
short unsigned int j;
j = 50000;
i = j;
cout << i << " " << j;
return 0;
}
当上面的程序运行时,会输出下列结果:
-15536 50000
对于 unsigned short 类型,所有的位都被解释为数值位。因此,二进制 1100001101010000
直接被解释为50000
。对于 short 类型,有符号整数使用二进制补码表示法,其中最高位(左)是符号位。所以最终解释为-15536
了
C++类型限定符、存储类
类型限定符/存储类 | 定义 |
---|---|
const | 常量,不能被修改 |
volatile | 该变量的值可能被当前程序以外的因素改变 |
restrict | 用于限定和约束指针,并表明该指针是访问这块内存数据对象的唯一且初始的方式 |
mutable | 类中的成员变量可以在 const 成员函数中被修改 |
static | 静态变量,该变量的作用域仅限于当前文件或当前函数内,不会被其他文件或函数访问 |
register | 寄存器变量,表示该变量被频繁使用,可以存储在CPU的寄存器中,以提高程序的运行效率 |
extern | 相当于提供一个全局变量的引用,可以理解为在另一个文件中声明一个全局变量或函数 |
thread_local | 线程本地存储变量,该变量仅可在它在其上创建的线程上访问,避免数据竞争和同步问题,在创建线程时创建,并在销毁线程时销毁 |
C++运算符
算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、杂项运算符
杂项运算符 | 描述 |
---|---|
sizeof | 返回变量字节数 |
A ? X:Y | 条件运算 |
, | 逗号运算符,按顺序求解表达式,整个逗号表达式的值是最后一个表达式的值,其余值被丢弃 |
.和-> | 成员运算符,用于引用类、结构和共用体的成员 |
Cast | 强转 |
&和* | 指针运算符,返回变量地址和指向一个变量 |
C++函数
Lambda函数与表达式
Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。具体形式如下:
[capture](parameters)->return-type{
body}
其中:
- capture:捕获值,用于指定Lambda表达式可以访问的外部变量,以及是按值还是按引用的方式访问。
- parameter:参数列表。
- return type:返回值类型。
- function body:函数体
捕获方式
- 值捕获:在捕获列表中使用变量名,表示将该变量的值拷贝到 Lambda 表达式中。值捕获的变量默认不能在 Lambda 表达式中修改,除非使用
mutable
关键字。
int x = 10