C++入门1--命名空间、引用与函数重载
主要内容:
1.命名空间
2.c++的输入与输出
3.缺省参数
4.函数重载
5.引用
6.内联函数
7.auto关键字
8.基于范围的for循环
9.空指针–nullptr
1.命名空间
1.1为什么要有命名空间呢?:1.全局作用域里面的变量,类(后面会提到的)和函数的名称可能会与 关键字 冲突 2.在进行一个大工程的时候,通常是几个程序原分开写一部分功能,然而当几个文件合并的时候,那些定义在全局域里面的变量,类,核函数名称可能会相互冲突,所以就引出了我们的命名空间
1.2命名空间的作用: 命名空间就是对标识符的名称进行本地化,以避免命名冲突或者名字污染。
1.3命名空间的定义: 命名空间需要一个关键词namespace(顾名思义,命名空间),然后接上你给这个命名空间取的名字,最后再加上{}即可。
1 |
|
注意:1.命名空间要定义在全局域中 2.命名空间可以进行嵌套 3.命名空间同一个工程中如果遇到相同名称的命名空间, 编译器 会把他们合到一起
补充 : 预编译阶段,#include 会将头文件的内容直接替换到当前文件中(类似 “文本拷贝”),这是预处理的基本行为,C++ 标准库的标识符(如 cout、cin、vector 等)通常定义在 std 命名空间中!!!!!所以我们在包含了有文件以后如果要是用哪个变量,还需要使用作用域限定符
1.4命名空间的使用的三种方式:
1.命名空间的名称+::(作用域限定符)+要 使用 的变量的名称
1 |
|
2.可以在全局中使用using将命名空间中的某个成员单独进行引用
1 |
|
3.可以直接展开某个命名空间
1 |
|
补充:
1.编译器搜索变量的顺序:局部域->全局域
2.我们一般不会把命名空间域给展开,因为命名空间本来就是帮助我们在全局中定义一些名字冲突的变量,类型或者函数,所以我们一般都指定访问
2.c++的输入&输出
说明:1.C++的输入输出更方便,可以自动识别变量的类型
2.cout是流输出运算符,cin是流输入运算符,他们包含在
这个头文件中, 在使用时我们通常会用到<<流插入运算符,>>流提取运算符
1 |
|
3.缺省参数
缺省函数的概念: 给函数的形参指定一个确定的值,在调用该函数的时候,如果没有指定实参,那么就使用形参。
注意:1.缺省参数的值只能在函数声明的时候给 ,原因:在 预处理 阶段编译器会把头文件展开,展开以后各自的.c++文件会单独进行编译,并不会合到一起,如果你将缺省参数给了定义,那么在编译阶段会出错,因为在语法上面就不对了,你明明定义这个函数有两个参数,你却只传了一个参数
2.半缺省参数必须要从右往左依次给出,因为传参的时候默认传给的是没有定义的参数。
3.缺省值必须是常量或者全局变量
4.函数重载
函数重载的概念:c++允许在同一个作用域中声明几个同名函数,这些函数的形参列表不同(参数个数,类型,类型顺序)
注意:和返回值没有关系
1 | void fun(int a, char* b) |
5.引用
引用就是给变量取一个别名,你对引用进行操作的时候,其实就是对变量进行了操作
注意事项:
1.在定义引用的时候就必须初始化
2.一个变量可以有多个引用
3.引用一旦引用一个实体,就不能再引用其他实体
4.在引用过程中,权限只能平移或者缩小,不能放大
5.引用的类型必须要和实体的类型保持相同
一些重要的事例:
eg1:引用的权限不能放大
1
2
3
4
5
6 int main()
{
const int a = 10;
int& b = a;
return 0;
}注:a这个变量的值不能更改,如果按照上面的方式去引用a明显破坏了语法规则,所以编译器是不能通过的
eg2:引用权限不能放大的变式(类型转换)
1
2
3
4
5
6
7
8 int main()
{
double a = 10.1;
int b = a;//√
const int& c = a;//√
int& d = a;×,因为中间生成的临时变量具有常性,所以要用const修饰一下
return 0;
}因为在类型转换的时候,会生成一个中间的临时变量,临时变量具有常性,可以认为是一个常量
引用的使用场景:
1.做参数:就相当于在c语言里面的指针,看下里面的代码
1 | void Swap1(int* a, int* b) |
在传参数的时候可以不用取地址了,更加方便一点
2.做返回值:在学习引用返回之前我们先了解一下值返回,值返回的本质其实是拷贝,也就是先生成一个临时变量,然后再返回回去,然而我们的引用返回就有点像是指针返回了那个地址处的值,这样做可以提升效率,但同时伴随着危险,也就是非法访问。【所以引用返回有几个使用条件:该变量不能是临时变量,也就是再出了作用域之后,该空间不会被操作系统收回。(符合这种条件的有静态变量,也有用malloc开辟的空间)】
引用和指针的不同点:
1、引用在概念上是定义了一个变量的别名,而指针式存储一个变量的地址
2、引用在定义的时候必须初始化
3、引用在初始化时引用过一个实体以后,就不能再引用其他的实体,而指针可以在任何时候指向任何同一类型的实体
4、没有NULL引用!!!(也就是说必须要初始化成一个不为NULL的实体)但有NULL指针
5、在sizeof中的含义不同,引用在sizeof中指的是引用对象类型的大小,然而指针则是地址空间所占字节个数的大小
6、引用自加表示实体+1,然而指针自加表示指针向后偏移一个类型的大小!!!!!
7、在引用过程中,权限可以平移或者缩小,但是不能够放大!!!!!!!!
8、有多级指针但是没有多级引用
9、引用比指针相对来说更安全
10、访问实体的方式不同,指针需要解引用(显式),然而引用是编译器自己处理的
6.内联函数
概念:以inline修饰的函数叫内联函数,c++编译器会在调用内联函数的地方展开,这样就没有 函数调用 建立栈帧的开销(所以是用范围就是短小函数的频繁调用)
内联函数其实就是一种空间换时间的做法,底层原理是在编译阶段经函数调用替换成函数体,但是可能会使目标文件变大。而且inline只是一种请求没如果函数的行数过多,比那一期可能不会采用内联函数
注意:内联函数的生命和定义不要分开
7. auto 关键字
auto的概念:auto是一个类型指示符,在编译阶段编译器会自动推导auto修饰的变量的类型。
值得注意的是:在使用auto定义一个变量的时候,必须要进行初始化,因为在编译阶段编译器就是要根据这个表达式来推断auto的实际类型。所以auto并不是一种类型的声明,而是一种类型声明时的占位符,在编译阶段编译器会把auto替换成变量实际的类型。
auto的使用细则:
1.auto声明指针类型时,auto*和auto没有任何区别,但是auto声明引用类型时必须要加上一个&
2.在同一行使用auto定义多个变量时,那些变量的类型必须相同,否则编译器会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量
1
2
3
4
5
6 >using namespace std;
int main()
{
auto c = 10, d = 20;
auto e = 10, f = 1.1;
}
auto不能推导的场景 :
1、auto不能作为函数的参数
因为之前讲过编译器是根据表达式来推断变量类型的
2、auto不能不能用来声明数组
比如:auto b[] = {4,5,6}是不行的
8.基于范围的for循环
如果要访问一个有范围的集合,可以用for循环,for循环后的括号内部由:隔开,第一部分是迭代的变量,第二部分是迭代的范围

注意:for循环的使用条件:迭代的范围必须是确定的
1 | void rxj(int a[]) |
9.空指针–nullptr
在c++中,NULL被定义为字面常量0,或者定义成无类型指针常来那个,但是编译器在默认情况下会将其定义成0,会产生一些麻烦,所以我们就引出了空指针nullptr

