目录1 域2 namespace 关键字2.1 命名空间的定义2.2 命名空间的使用2.3 命名空间的作用3 缺省参数4 函数重载5 引用5.1 引用的概念5.2 const 引用5.3 引用的使用场景5.4 引用和指针的区别6 inline 关键字7 nullptr1 域在 C 中域包括了函数局部域全局域命名空间域类域函数局部域由函数的大括号所包裹起来的区域局部变量所处的位置全局域不受大括号影响的区域全局变量所处的位置命名空间域由 namespace 关键字限制的区域类域由 class 或 struct 关键字限制的区域2 namespace 关键字2.1 命名空间的定义使用 namespace 关键字可以定义一个命名空间命名空间本身也是一个域命名空间内可以定义函数变量等并且命名空间只能在全局进行定义具体语法为namespace命名空间名称{//命名空间的内容}命名空间也可以嵌套定义namespaceA{inta0;namespaceB{intb0;}}2.2 命名空间的使用如果要访问命名空间中的内容有三种方式使用命名空间名字访问较为推荐的方法#includeiostreamusingnamespacestd;namespaceA{inta0;namespaceB{intb0;}}intmain(){//使用命名空间名字coutA::aendl;// ::为域作用限定符coutA::B::bendl;return0;}使用 using 将命名空间的某成员展开如果某成员不会发生命名冲突可以用这个方式展开#includeiostreamusingnamespacestd;namespaceA{inta0;namespaceB{intb0;}}//展开成员usingA::a;usingA::B::b;intmain(){coutaendl;coutbendl;return0;}使用 using 将整个命名空间展开这个方法在大项目中可能会存在命名冲突的问题不太推荐#includeiostreamusingnamespacestd;namespaceA{inta0;namespaceB{intb0;}}//展开整个命名空间usingnamespaceA;usingnamespaceB;intmain(){coutaendl;coutbendl;return0;}2.3 命名空间的作用在 C 语言中经常会因为调用了某个头文件而产生变量名与函数名的命名冲突问题命名空间就是为了处理这种问题而存在的比如#includestdlib.hintrand0;intmain(){coutrandendl;return0;}这段代码中定义了一个全局变量 rand但是头文件 stdlib.h 中有一个函数的名称也是 rand就导致命名冲突可以用命名空间来解决这个问题#includestdlib.hnamespaceA{intrand0;}intmain(){coutA::randendl;//使用命名空间A中的randrand();//调用rand函数return0;}3 缺省参数C在定义函数时可以在定义参数时给参数缺省值默认值这个参数就被叫做缺省参数在调用函数时如果没有传参那么就会使用该缺省值如果传参了就会使用传入的值具体形式为intfunc(intx0)//x为缺省参数有默认值0{coutxendl;}intmain(){func();return0;}缺省参数有全缺省和半缺省全缺省函数的每个参数都有自己的缺省值intAdd(intx0,inty0)//全缺省{returnxy;}intmain(){Add();return0;}半缺省函数的部分参数有自己的缺省值intAdd(intx,inty0)//半缺省{returnxy;}intmain(){Add(1);return0;}在语法规定中半缺省参数一定要从右往左进行缺省不能进行跳跃缺省intAdd(intx0,inty)//不能从左往右缺省{returnxy;}intfunc(inta0,intb,intc0)//不能跳跃缺省{//...}不管是全缺省还是半缺省在传参时参数列表必须是从左往右依次传入实参intfunc(inta0,intb0,intc0){//...}intmain(){func(1,1);//从左往右依次传参func(,,1);//不能从右往左传参return0;}函数的声明和定义中不能同时出现缺省值必须在声明中给缺省值4 函数重载函数重载主要会在下面几种情况下发生函数名相同形参列表变量个数相同但变量类型不同intAdd(intx,inty){returnxy;}doubleAdd(doublex,doubley){returnxy;}函数名相同形参列表变量类型相同但变量个数不同intAdd(intx,inty){returnxy;}intAdd(intx){returnx10;}函数名相同形参列表变量类型个数都不相同intAdd(intx,inty){returnxy;}doubleAdd(doublex){returnx10.0;}不会发生重载的情况函数名相同形参列表变量类型个数都相同但是返回值不同intAdd(intx,inty){returnxy;}doubleAdd(intx,inty){returnxy;}会发生重载但是无法判别函数的情况函数名相同但是一个是无参一个是全缺省参数voidfunc(){//...}voidfunc(inta0,intb0){//...}因为全缺省参数和无参的函数都可以不用传实参所以在调用时如果不传实参编译器无法判定使用哪个函数5 引用5.1 引用的概念定义一个引用就相当于是给一个变量取了别名引用在定义时是不开辟新空间的它和被引用的变量使用同一块内存空间C中可以使用来定义一个引用一个变量可以有多个引用intmain(){inta0;intraa;//给a取别名为rareturn0;}在使用引用时要注意引用必须要进行初始化intrb;//这种写法是错误的引用不能更改它的指向intmain(){inta0;intraa;intb0;rab;//赋值没有改变引用的指向return0;}把 b 赋值给 ra 的行为不是改变了 ra 的指向而是将 0 赋值给了 a5.2 const 引用用 const 修饰引用就是 const 引用const 引用可以对被引用的对象进行读取但是不能更改被引用对象的值const 引用可以用来引用普通对象和 const 修饰的对象但是不能用普通引用来引用 const 修饰的对象const 引用指向普通对象intmain(){inta0;constintraa;return0;}a 是普通的对象它即可读又可写ra 是 const 引用对引用的对象可读不可写权限进行了缩小const 引用指向 const 修饰的对象intmain(){constinta0;constintraa;return0;}a 是 const 修饰的对象它可读不可写ra 是 const 引用对引用的对象可读不可写权限进行了平移普通引用指向 const 修饰的对象intmain(){constinta0;intraa;return0;}a 是 const 修饰的对象它可读不可写ra 是普通引用对引用的对象可读可写权限进行了放大无法进行编译特殊情况C中如果发生了隐式类型转换或表达式求值都会产生一个临时对象用来存储结果临时对象具有常性如果要让引用指向这个临时对象那么该引用需要const 修饰intmain(){inta1;constintra(a2);constdoublerba;return0;}5.3 引用的使用场景函数在进行传值调用与返回的时候会对参数进行拷贝此时如果该参数占的空间较大则会耗费不少的时间来处理引用主要是在函数传参和返回时使用用来减少函数传参和返回时产生的拷贝和在函数体内改变对象constintAdd(intra,intrb){returnrarb;}intmain(){inta0;intb1;Add(a,b);return0;}在引用作返回值时需要注意引用也会存在野引用的问题intfunc(){inta0;intraa;returna;}intmain(){func();return0;}func 内定义了 a返回了 a 的引用但是 a 是局部变量所以函数结束时会销毁那么 ra 就会变成野引用5.4 引用和指针的区别在C中引用和指针相辅相成各有各的特点在定义时引用是不开辟新空间的只是一个变量的别名指针则需要开辟空间来保存地址在初始化时引用必须要进行初始化否则会有编译错误指针建议初始化但不是必须的在修改时引用不能修改指向指针则可以通过修改保存的地址来变更指向在大小上引用的大小就是指向的对象的大小指针的大小在 32 位机器下是 4B64位机器下是 8B在访问上引用直接可以访问指向的对象指针则需要解引用来访问在安全性上引用一般不存在空引用和野引用的问题指针则会存在空指针和野指针的问题引用相对更为安全6 inline 关键字C 语言中可以把逻辑较为简短的函数写成宏的形式减少函数调用时栈帧创建的时间损耗但是写成宏容易出现问题所以 C 引入了 inline 关键字inline 是用来修饰函数的关键字被它修饰的函数叫内联函数编译时会在调用内联函数的地方将它展开不需要创建栈帧即可使用函数提升了效率也避免了宏的问题毕竟写函数一般都不会写错inlineintAdd(intx,inty)//内联函数{returnxy;}intmain(){Add(1,2);//直接展开return0;}需要注意的是并不是所有加了 inline 的函数都会直接展开这取决于编译器编译器会根据函数内代码的多少来斟酌展开代码量过多的函数如果成为内联函数并在很多地方展开那么会导致整个项目的代码量急剧上升效率下降因此一般只建议让代码量少的函数成为内联函数内联函数不支持声明和定义分离7 nullptrC 语言中NULL 是 void* 类型的常量可以用来给任何类型的指针赋值所以在函数调用时就能够匹配形参为指针类型的函数C 中NULL 被定义为了 0此时通过传 NULL 来调用函数时就会匹配至形参为整形的函数而非形参为指针类型的函数使用与 C 语言有所区别所以在C中定义了 nullptr 作为空指针它可以用来给任何类型的指针赋值intfunc(int*p){coutfunc(int*)endl;}intfunc(intx){coutfunc(int)endl;}intmain(){func(NULL);//调用func(int x)func(nullptr);//调用func(int* p)return0;}