[原创][第I部分][编程基础]我的C++ 98复习并升级到C++20的复习旅途

[简介]
常用网名: 猪头三
出生日期: 1981.XX.XX
QQ: 643439947
个人网站: 80x86汇编小站 https://www.x86asm.org
编程生涯: 2001年~至今[共22年]
职业生涯: 20年
开发语言: C/C++、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python
开发工具: Visual Studio、Delphi、XCode、Eclipse、C++ Builder
技能种类: 逆向 驱动 磁盘 文件
研发领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全/macOS应用软件安全
项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测

[序言]
最近在努力地学习C++20的相关知识点, 给自己订下一个小目标: 把自身已掌握的陈旧C++98, C++03逐步升级到C++20. 以适应现代C++开发的要求. 在学习和复习的过程中, 顺便记录疑惑点. 该复习过程会经历现代C++开发5大理论的学习. 当前已经完成了[第I部分][编程基础]的学习任务. 下一个阶段会进入[第II部分]的学习.

[第I部分][编程基础][总结列表, 有些细节, 会配备相应的代码来解释]

1> 基础类型变量初始化

int total{0} ;

2> 基础类型之间的显示转换

double average{static_cast(total) / gradeCounter} ;


语法解释: 使用static_cast进行强制显示转换, 把int类型提升至double.
表达式作用: 把total的临时double拷贝除以int类型的gradeCounter.

3> 格式化浮点数

std::cout << setprecision(2) << fixed << L"Class average is " << average << L"\n" ;


表达式作用: setprecision(2)将浮点数的精度设置为两位小数, 默认四舍五入. fixed强制浮点数不能使用科学记数法格式显示. fixed也可以强制打印小数点和尾随的零. 例如:88.00.

4> 数字分隔符

long long value1{9'223'372'036'854'775'807LL} ; // max long long vaule


语法解释: 为了增强字面值的可读性, 并减少打字错误, C++14引入数字分隔 ' (单引号字符). 另外LL表示字面值指定为long long整数.

5> swtich case break的"直通"行为: [[fallthrough]]特性

6> C++ 20新型格式化

std::cout << format("{}'s grade is {}\n", student, grade) ;


表达式作用: 可以使用{}大括号了进行格式化.

7> 短路求值
语法解释: 使用了&&或||操作符的组合表达式如果提前知道结果, 那么会立即停止求值.
例子:

(gender == FEMALE) && (age >= 65)


如果gender不等于FEMALE, 那么整个组合表达式必定为假, 所以会立即停止求值, 不会继续求值age >= 65.

8> C++11开始大量引入新的数学函数

9> 配合"准则支持库"的收缩转换: narrow_cast

gsl::narrow_cast(7.5)


语法解释: 将double值7.5转换为int值7

10> C++11提供更安全的随机数功能库

11> enum class

12> C++11指定枚举常量的类型

enum class Status : short {keepRolling, won, lost}


语法解释: 将enum class Status中的常量类型指定为short类型

13> 块作用域
在嵌套块中, 如果外层块中的标识符与内层块中的标识符同名, 那么外层块中的标识符将被"隐藏", 直到内层块结束. 内层块"看到"的是自己的局部变量的值, 而不是包围它的那个块的同名变量值. 如果不小心为内层块中的标识符使用了和外层块的标识符相同的名称,  而事实上你想让外层块中的标识符延续到内层块, 那么通常都是一个逻辑错误. 

[原创]C++98升级到C++20的复习旅途-“作用域规则“-CSDN博客

14> 内联函数(inline function)
作用: 从软件工程的角度来说, 将程序作为一组函数来实现是不错的. 但函数调用涉及执行时间和资源的开销. C++提供了"内联函数"(inline function)来帮助减少函数调用的开销. 在函数定义的返回类型前附加一个inline关键字, 即可让编译器在调用该函数的每个地方都生成函数主体代码的一份拷贝(如果可以的话), 从而避免函数调用. 这通常会使程序变大. 编译器有可能会忽略inline的限定符.  另外编译器可能会自动内联你没有显示添加inline的代码. 但"C++核心准则"指出, 只应对"小的, 对执行时间要求高"的函数进行内联.

15> 引用, 引用参数, const引用
作用: 如果传递的是对变量的引用, 调用者相当于允许被调用者的函数直接访问在调用者中的这个变量, 而且允许对方修改该变量. 传引用有利于性能, 因其可以避免传值时对大量数据进行拷贝的开销.

int& number; 
viod displayName(const std::string& name);


语法解释: "number是对一个int的引用" "name参数是对一个string的引用, 该引用是常量. 被调用者不能修改调用者的值"

16> 默认参数
注意事项: 默认参数必须是函数参数列表最右边(靠近尾部)的参数. 调用具有两个或者多个默认参数的函数时, 如果一个被省略的实参不是最右边的那个, 该实参右边的所有实参也必须是省略的.

int boxVolume(int length=1, int width=1, int height=1); //合法
int boxVolume(int length, int width, int height=1); //合法
int boxVolume(int length=1, int width, int height); //非法
int boxVolume(int length=1, int width, int height=1);//非法
int boxVolume(int length=1, int width, int height);//非法

17> 一元作用域解析操作符(unary scope resolution operator), 即 ::
作用: 如果当前作用域有一个和全局变量同名的局部变量, 就可以使用该操作符访问变量的全局版本. 

#include 
#include 

const int number{7} ;

int _tmain(int argc, _TCHAR* argv[])
{
    // 让控制台程序支持显示中文
    std::locale::global(std::locale("")) ;

    const double number{10.5} ;

    std::wcout << L"局部double number变量: " << number << std::endl;
    std::wcout << L"全局int number变量: " << ::number << std::endl;

}

18> 函数重载
注意事项: 同一个参数列表, 不同的返回类型, 像这样创建重载函数也会造成编译错误. 编译器只根据参数列表来区分重载函数. 重载函数不需要有相同数量的参数. 另外有默认参数的函数在调用时可能与另一个重载函数发生冲突; 这也会造成编译器错误. 例如: 假定程序中有一个函数显示地不获取任何实参, 另一个同名函数则全部包含默认参数, 那么一旦调用这个名字函数, 同时不传递任何实参,  两者就会产生歧义, 因为编译器无法判断应该调用函数的哪个版本.

19> 函数模板. 模板编程也叫泛型编程
注意事项: "函数模板"其实是源于"函数重载"的思想, 说白了"函数模板"就是针对参数类型重载, 在函数的参数列表用中 所有参数的类型都用一个简单的字符代替了. 比如用 T 这个字母就可以代替所有类型int, double, char 等等. 

[原创]C++98升级到C++20的复习旅途-“函数模板“-CSDN博客

20> 操作数的求值顺序
注意事项: 从C++17开始, 还为其他多种操作符规定了操作数的求值顺序. 比如 [],->, (), <<, >>, .*和->*操作符, 编译器都会从左到右求值操作数.

[结尾]
这份列表, 不合适零基础的C++学习者, 仅仅合适有基础的读者阅读, 方便这类有基础的读者有一个快熟的总结. 

你可能感兴趣的:(C/C++探究,c++,c++20,开发语言)