C++ 学习笔记(三)
这次看的东西有点多..哦不..是看的有点随便..翻一翻就过去了... 感觉有点基础..?(怕不是自己太菜) 所以随便记一下好了..
命名的强制类型转换
//强制类型转换的形式
cast-name<type>(expression); //type 为目标类型,expression是要转换的值
//cast-name则为{static_cast,dynamic_cast,const_cast,reinterpret_cast}中的一种 下面记录一下各个cast-name的意义
static_cast
任何具有明确意义的类型转换,只要不包含底层const,都可以使用static_cast
可以将大的算术类型转换为小的算术类型,而不产生warning
可以用其将存在void指针中的值转化出来,即:
double d = 10; void *p = &d; double *dp = static_cast<double*> p; //要注意的是避免转换后所得类型与指针类型不符,否则产生未定义后果
const_cast
对于常量对象转换为非常量对象的行为,即去掉const性质
const_cast仅能去掉const性质,不能转换类型
renterpret_cast
为运算对象的位模式提供较低层次的重新解释
emm...读不懂 大概意思就是..随便转换...? 就算转换完不能用也可以转换...所以转换时一定要明确其根本类型,就是它内部存的到底是什么类型,所以说使用它是非常危险的...现在的菜鸡水平还是先把它放在一边吧..
c++运算符优先级顺序表
网上搬个优先级表😁
| 优先级 | 运算符 | 描述 | 结合性 |
|---|---|---|---|
| 1 | :: | 作用域解析 | 从左到右 |
| 2 | a++ a-- | 后缀自增与自减 | |
*type*() *type*{} | 函数风格转型 | ||
a() | 函数调用 | ||
a[] | 下标 | ||
. -> | 成员访问 | ||
| 3 | ++a --a | 前缀自增与自减 | 从右到左 |
+a -a | 一元加与减 | ||
! ~ | 逻辑非和逐位非 | ||
(*type*) | C 风格转型 | ||
*a | 间接(解引用) | ||
&a | 取址 | ||
sizeof | 取大小[注 1] | ||
co_await | await 表达式 (C++20) | ||
new new[] | 动态内存分配 | ||
delete delete[] | 动态内存分配 | ||
| 4 | .* ->* | 成员指针 | 从左到右 |
| 5 | a*b a/b a%b | 乘法、除法与余数 | |
| 6 | a+b a-b | 加法与减法 | |
| 7 | << >> | 逐位左移与右移 | |
| 8 | <=> | 三路比较运算符(C++20 起) | |
| 9 | < <= | 分别为 < 与 ≤ 的关系运算符 | |
> >= | 分别为 > 与 ≥ 的关系运算符 | ||
| 10 | == != | 分别为 = 与 ≠ 的关系运算符 | |
| 11 | a&b | 逐位与 | |
| 12 | ^ | 逐位异或(互斥或) | |
| 13 | ` | ` | 逐位或(可兼或) |
| 14 | && | 逻辑与 | |
| 15 | ` | ` | |
| 16 | a?b:c | 三元条件[注 2] | 从右到左 |
throw | throw 运算符 | ||
co_yield | yield 表达式 (C++20) | ||
= | 直接赋值(C++ 类默认提供) | ||
+= -= | 以和及差复合赋值 | ||
*= /= %= | 以积、商及余数复合赋值 | ||
<<= >>= | 以逐位左移及右移复合赋值 | ||
&= ^= ` | =` | 以逐位与、异或及或复合赋值 | |
| 17 | , | 逗号 | 从左到右 |
局部对象
在c++中,名字有其作用域,对象有生命周期
局部静态对象(static)
局部静态对象即在程序第一次调用函数时对其初始化,并直到程序结束才被销毁,且函数结束对其不产生影响
size_t const_calls()
{
static size_t cnt = 0;
return ++cnt;
} 如上就是一个统计函数被调用多少次的函数,用到static 静态变量
const形参与实参
当用实参初始化形参时,会忽略掉顶层const
函数参数定义时应尽量使用常量引用,即:
void func(const int &n)
使用普通引用是一种较为常见的错误:令使用者认为可以改变其实参的值,而且大大限制了参数范围(无法传入常量)
(当然若函数体需要改变其实参的值,则必须使用普通引用)
数组形参
可以利用引用显式的传递一个固定大小的数组形参
void func(int (&arr)[10]); //传递一个大小为10的int数组
由于c++中没有真正的多维数组,所以声明二维数组时,可以声明为指向数组的指针
void func(int (*arr)[10]); //传递一个指向大小为10的数组的指针 void func(int arr[][10]); //等价定义
main()函数的传参
有些情况下我们需要给main传参而main的参数为
main(int argc, char **argv);
传参方法:可以通过运行可执行文件时在命令行后添加字符串实现(传入参数为argv,而argc为argv中字符串的个数)
$ g++ a.cpp -o a $ ./a a b c d
initializer_list类型
当函数实参数量未知,但类型相同,可使用initializer来传参,但传参需要加上{}
initializer_list与其他容器不同的是,它内部元素永远是常量值,不能被改变。
//标准库提供的操作
initializer_list<T> lst;
initializer_list<T> lst{a,b,c...};
lst2(lst);
lst.size();
lst.begin();
lst.end(); //即可以使用范围for循环 函数返回数组指针方法
返回数组指针的函数形式如下:
Type (*func(para_list)) [dimension]; //dimension为数组大小 int (*func(int i))[10]; //返回指向大小为10的int类型数组指针
也可以使用尾置返回类型
auto func(int i) -> int(*)[10];
或者使用decltype():
int arr[10]; decltype(arr) *func(int i);


