概念提纲
知识框架参照cppreference。
形而上的编程
编程范式<=>编程语言概念<=>编程语言提供的实现
“面向对象”(OOP)的概念套餐
- 封装
- 继承
- 多态
面向对象的三大特性 - Leo Chin - 博客园
编程范式的新发展
- 组合
《冒号课堂:编程范式与OOP思想》之编程范式笔记 | coderbee笔记
基础知识
类型和“右左法则”
- “先中再右最后左”
- 变量首先被离它最近的类型修饰,且优先被括号中的类型修饰;
- 其次被它的后缀修饰;
- 紧跟圆括号表示是函数:如R V(Args)——V是一个函数(如果V是指针则表示V是一个函数指针),括号的Args为参数类型,R是返回值类型;
- 紧跟方括号表示是数组:如T A[N]——A是一个数组(如果A已经是指针则表示A是一个指向数组的指针/数组指针),方括号中如果有N则为数组元素个数,T是数组元素类型;
- 再次被它的前缀修饰;
- 星号表示是指针;如C* P,P是一个指针,指针指向的类型继续推断;
- C++的类型声明有如下限制:
- 函数的返回值不能是函数,但可以是函数指针;
- 函数的返回值不能是数组,但可以是数组指针;
- 数组的元素不能是函数,但可以是函数指针;
- 数组的元素可以是数组;
关于const
如何读带有const关键字修饰的类型:从右往左读;
- const默认作用于它左边的类型,当左边没有类型时作用于右边的类型;
- PS:还有一些方法说的是:如果const后面是类型,则修饰类型,其余情况修饰相邻的指针星号;——这个是错的
int * const p; // p是一个不可修改的指针变量,指向int类型;const pointer to int(常指针)int const *p; // p是一个指针,指向一个不可修改的int类型变量;pointer to const int(指向常量的指针)const int *p; // p是一个指针,指向一个不可修改的int类型变量;pointer to const int(指向常量的指针)int const * const p; // p是一个不可修改的指针变量,指向一个不可修改的int类型变量;const pointer to const intconst char *pChr = "hello"; // pChr是一个指针,指向一个(实际上是一段)不可修改的char类型变量;// 该情况下指针是可以重新赋值的,如 pChr = "world"; 但不能更改pChr的内容;char * const cpChr = "hello"; // cpChr是一个不可改变的指针,指向一个char类型变量;// 该情况下如果修改cpChr,如 pChr = "world"; 编译时会报错;但可以更改pChr的内容,尽管在运行时这样做不正确;
- 函数相关的const
- 对于普通函数,如 const R func(Arg); // 这个const修饰返回值
- 对于成员函数,除了返回值const之外,函数声明后面的const表示常成员函数;
- 如 R C::func(Arg) const; // 这里的const表示不允许修改this指向的对象;实际this是一个指向const类型对象的const指针;(如果不是常成员函数,this的指向也不可以修改,相当于const指针)
ref: C++函数前和函数后加const修饰符区别 - MATU - 博客园
溢出和回绕
相关CWE:CWE-191: Integer Underflow (Wrap or Wraparound)整数下溢_plstudio1的博客-CSDN博客
- 如何判断整数运算是否溢出_EasonDongH的博客-CSDN博客
可以根据实际情况,将运算数限制在一个有限的范围内,或假设运算数在某个范围内;
- 或者根据实际业务逻辑,在运算前或运算后进行判断;
- 使用ubsan进行检查;
PS:溢出、上溢(Overflow)和下溢(Underflow)、回绕(Wrap Around)
无符号数(回绕)
加法:和不小于任意一个数则没有溢出;和小于任意一个加数则溢出了;
- 减法:(运算前后)被减数不小于减数则不会溢出;被减数小于减数则会溢出;小的减大的会变负数(下溢);
- 乘法:(运算后)用除法逆运算,结果一致就没有溢出;
- 这里给出了一个复杂的方法:C/C++ 判断两个整数相乘是否溢出 - DOF_KL - 博客园
- 这里的观点是用long long装结果:Check for integer overflow on multiplication - GeeksforGeeks
- 除法:
不会溢出;拿linux的实现举例:我们知道,在乘法运算本身溢出,不会抛出fault;但如果在除法运算时下,会抛出SIGFPE;- 例如:对于使用int类型计算如下两个结果
int res1 = -2147483648 % -1int res2 = -2147483648 / -1
- 例如:对于使用int类型计算如下两个结果
有符号数
- 加法:只有同号的两个数相加会溢出,(运算后)如果两个加数同号且结果变号说明溢出;
- 减法:只有异号的两个数相减会溢出,(运算后)如果正数减负数得出负数,或者负数减正数得出正数说明溢出;
- 乘法:(运算后)如果有任意乘数为0,不会溢出;
控制流
跳转
注意goto的标号只能在一个函数里跳转;
长跳转需要使用setjmp和longjmp
表驱动(跳转)
在C++的类中使用表驱动,减少代码中的if-else或switch;
enum
默认从零开始递增;除非定义第n个值为特定值x,这样会使得第n个值以后从x开始递增;
运算符
资料
- https://www.youtube.com/watch?v=eSDVVrjFh54&ab_channel=C%E1%90%A9%E1%90%A9WeeklyWithJasonTurner
https://www.youtube.com/watch?v=UztsWf7F_Sc&ab_channel=CppCon
- Standard C++ (isocpp)
- Leanpub: Publish Early, Publish Often
- wg21
- Draft C++ Standard: Contents
- blogs
- youtube
- C++ weekly with jason Turner
- The Cherno
- CppCon
- Bisqwit
- javidx9
- Meeting Cpp
工具
