1.命名空间1.1 namespace 的价值使用命名的目的是对标识符的名称进行本地化一避免命名冲突或名字污染1.2 namespace 的定义^ 定义命名空间需要使用到 namespace 的关键字后面跟命名空间的名字然后接一对{}即可{}中即为命名空间的成员。命名空间中可以定义变量函数类型……^ namespace 本质是定义出一个域这个域跟全局域各自独立不同的域可以定义同名变量^ C中域有函数局部域全局域命名空间域类域域影响的是编译时语法查找一个变量/函数/类型出处的逻辑所以有了域隔离名字冲突就解决了。局部域和全局域除了影响编译查找逻辑还会影响变量的生命周期命名空间域和类域不影响变量生命周期。^ namespace 只能定义在全局但也可以嵌套定义。^ 多文件中可以定义同名 namespace 他们会默认合并到一起就像同一个 namespace 一样#includestdio.h #includestdlib.h namespace lee { // 命名空间中可以定义变量/函数/类行 int rand 10; int Add(int left, int right) { return left right; } struct Node { struct Node* next; int val; }; } int main() { // 这里默认是访问的是全局的 rand 函数指针 printf(%p\n, rand); // 这里指定 lee 命名空间中的 rand printf(%d\n, lee::rand); return 0; }1.3 namespace 使用编译查找一个变量的声明/定义时 默认只会在局部或者全局查找不会到命名空间里面去查找。所以我们要使用命名空间中定义的变量/函数有三种方式^ 指定命名空间访问项目中推荐这中方式^ using 将命名空间中某个成员展开项目中经常访问的不存在冲突的成员推荐这种方式^ 展开命名空间中全部成员项目不推荐冲突风险大#includestdio.h #includestdlib.h #includeiostream namespace lee { int a 666; int b 888; } int main() { // 指定命名空间访问 printf(%d\n, lee::a); // using 将命名空间中某个成员展开 using lee::b; printf(%d\n, b); //展开命名空间中全部成员 using namespace lee; printf(%d %d\n, a, b); cout a endl; return 0; }2. C 输入 输出^ iostream 是 Input Output Stream 的缩写是标准的输入输出流库定义了标准的输入输出对象。^ std::cin 是istream 类的对象它主要面向窄字符的标准输出流。scanf)^ std::cout 是 ostream 类的对象它主要面向窄字符的标准输出流。(printf)^ std::enl 是一个函数流插入输出时相当于插入一个换行字符串加刷新缓冲区。\n^ 是流插入运算符 是流提取运算符^ C的输入输出可以自动识别变量类型能更好的支持自定义类型对象的输入输出。^ cout / cin / endl 等都属于 C 标准库C 标准库都放在一个叫 std (standard) 的命名空间中所以要通过命名空间的使用方式去使用它们。#includeiostream using namespace std; int main() { // 在 io 需求比较高的地方加上以上 3 行代码 // 可以提高 C IO效率 ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int a 8; ; double b 1.1; char c x; cout a b c endl; cin a; cin b c; cout a b c endl; return 0; }3. 缺省参数^ 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时如果没有指定实参则采用该形参的缺省值否则使用指定的实参缺省参数分为全缺省和半缺省函数。有些地方把缺省参数也叫默认函数^ 全缺省函数就是全部形参给缺省值半缺省就是部分形参给缺省直。C 规定半去缺省参数必须从右往左依次连续缺省不能间隔跳跃给缺省值。^ 带缺省参数的函数调用 C 规定必须从左到右依次给实参不能跳跃给实参。^ 函数声明和定义分离时缺省参数不能在函数声明和定义中同时出现规定必须函数声明给缺省值。#includeiostream using namespace std; void Func(int a 0) { cout a endl; } // 全缺省 void Func1(int a 10,int b 20,int c30) { cout a a endl; cout b b endl; cout c c endlendl; } // 半缺省 void Func2(int a ,int b 20, int c 30) { cout a a endl; cout b b endl; cout c c endl endl; } int main() { Func(); // 没有传参时使用参数的默认值 Func(10); // 传参时使用指定的实参 Func1(); Func1(1); Func1(1, 2); Func1(1, 2, 3); Func2(1); Func2(1, 2); Func2(1, 2, 3); return 0; }4. 函数重载C 支持在同一个作用域中出现同名函数但是要求这些同名函数的形参不同可以是参数个数不同或者类型不同。这样 C 函数调用就表现出了多态行为使用更灵活。^ 返回值不同不能作为重载条件因为调用时存在歧义编译器不知道调用谁5. 引用5.1 引用的概念和定义引用不是新定义一个变量而是给已经存在的变量取链路一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用一块内存空间。类型 引用别名 引用对象#includeiostream using namespace std; int main() { int a 11; //引用b 和 c 是 a 的别名 int b a; int c a; //也可以给别名 b 取别名d 相当于还是 a 的别名 int d b; d; cout a endl; cout b endl; cout c endl; cout d endl; cout a endl; cout b endl; cout c endl; cout d endl; return 0; }5.2 引用的特性^ 引用在定义时必须初始化^ 一个变量可以有多个引用^ 引用一旦引用一个实体再不能引用其他实体5.3 引用的使用^ 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。^ 引用和指针在实践中相辅相成功能有重叠性但是各有特点互相不可替代。#includeiostream using namespace std; void Swap(int rx, int ry) { int tmp rx; rx ry; ry tmp; } int main() { int x 66; int y 88; cout x y endl; Swap(x, y); cout x y endl; return 0; }5.4 const 引用^ 可以引用一个 const 对象但是必须用 const 引用。const 引用也可以引用普通对象因为对象的访问权限在引用过程中可以缩小但是不能放大。^ 类似 int rb a * 3; double d 12.356; int rd d; 这样一些场景下 a *3 的结果保存子啊一个临时对象中在类型转换中会产生临时对象存储中间值也就是rb 和 rd 引用的都是临时对象而 C 规定临时对象具有常性所以这里就触发了权限放大必须要用常引用才可^ 所谓临时对象就是编译器需要一个空间暂存表达式的求值结果是临时创建的一个未命名的对象C 中把这个未命名对象叫做临时对象。5.5 指针和引用的关系C 中指针和引用就像两个性格迥异的亲兄弟指针是哥哥引用是弟弟在实践中他们相辅相成功能有重叠性但是各有自己的特点互相不可替代。^ 语法概念上引用是一个变量的取别名不开空间指针是存储一个变量地址要开空间。^ 引用在定义时必须初始化指针建议初始化但是语法上不是必须的。^ 引用在初始化时引用一个对象后就不能在引用其他对象而指针可以在不断地改变指向对象。^ 引用可以直接访问指向对象指针需要解引才是访问指向对象。^ sizeof 中含义不同引用结果为引用类型的大小但指针始终时地址访问所占字节个数32 位平台下占 4 个字节64 位下占 8 个字节。^ 指针很容易出现空指针和野指针的问题引用很少出现引用使用起来相对更安全一些。6. inline^ 用 inline 修饰的函数叫做内联函数编译时 C 编译器会在调用的地方展开内联函数这样调用内联函数就需要建立栈帧了就可以提高效率。^ inline 对于编译器而言只是一个建议也就是说你加了 inline 编译器也可以选择在调用的地方不展开不同编译器关于 inline 展开情况各不相同因为 C 标准没有规定这个。inline 使用于频繁调用的短小函数对于递归函数代码相对多一些的函数加上 inline 也会被编译器忽略。^ C 语言实现宏函数也会在预处理时替换展开但是宏函数实现很复杂很容易出错且不方便调试C设计了 inline 目的就是替代 C 的宏函数^ inline 不建议声明和定义分离到两个文件分离会导致链接错误。因为 inline 被展开就没有函数地址链接时就会出现报错。7. nullptrNULL 实际是一个宏^ C 11 中引入 nullptr nullptr 是一个特殊的关键字nullptr 是一种特殊类型的字面量它可以转换成任意其他类型的指针类型使用 nullptr 定义空指针可以避免类型转换的问题因为 nullptr 只能被隐式地转换为指针类型而不能转换为整数类型。