c++传言是机器语言中较为难学的语言之一。事实上,正如传言所闻,c++的入门确实很难。但是,世上无难事,只怕有心人。我相信大家在一起学习一起努力下,一定能一起攻克难关,征服c++。
1.概念:命名空间是c++语法,用来给一个特定域来命名。为特定域命名后相当于为这个域的所有内容加了把锁,在使用的时候要通过一定的方式解锁来使用域中的东西。
2.使用展示:
上图中,利用namespace定义一个新的域A,在主函数中要想调用A中的变量a必须指明a的域(域名::变量名)。另,std是c++语言中定义的标准库。
3.命名空间的特性:
a.域内可以定义变量、函数、类型(如结构体等)。(域定义的东西,具有全局性。比如域内定义的变量就是全局变量)
b.可以嵌套(嵌套层内的定义的变量,仍为全局变量)
4.意义:使用命名空间定义新的域可以影响编译器的查找规则(先局部后全局),不影响变量的生命周期。主要应用在写项目时,同事分工代码不会出现命名冲突。
5.访问命名空间的三种方法:
a.全部展开(这里展开指的是展开命名空间定义的域)
b.部分展开
c.完全不展开
其中cin、count都是定义在头文件< iostream >中,其特定域是std。
6.不同文件命名空间或者是同一文件嵌套多个命名空间可以同名,多个文件同名的命名空间会自动合并成一个命名空间。
7.同一个域不能定义多个同名变量!!!
1.定义:缺省参数是在声明或者定义函数的时候,给参数值从左向右赋于默认值。
2.类型:
a.全省参数
函数的参数全部赋于默认值。
b.半省参数 ==只能从左缺参==
函数的参数并不完全赋于默认值。
3.特性:
a.声明和定义不能同时在同一命名空间中
解决方案是缺省参数只写在声明上
b.缺省参数必须为常量或者是全局变量
1.定义:函数名称相同,但是函数参数列表并不相同(函数参数的个数、类型、类型顺序不同)
//函数参数个数不同的函数重载
//函数参数类型不同的函数重载
//函数参数类型顺序不同的函数重载
2.函数重载的原理:
编译器在编译过程中,将函数名称编号,将其于其地址整合称为符号表,再进行后续的编译过程。那c++编译器会将函数名和参数名进行相应的编号,通过名称的不同再开辟不同地址的空间。不同编译器的编号依据不同。
?? 小问题:返回值不同,但是参数列表相同的函数可以算的是函数重载吗?
!! 解答:并不是。因为我们调用函数的无法确定返回值,函数在创建栈帧的过程中会读取函数参数的类型开辟空间,系统就可以知道函数参数的类型。而返回返回值的时候,就会出现二义性。比如出现以下的程序:
返回返回值的时候到底是返回int类型还是double类型,我们是不可知的,是有歧义的。因此简单地讲,我们调用函数的时候无法明确返回值。这也是大佬在编写c++语言的时候为什么不将函数返回值也编入到函数名称里去。
1.认识引用:引用可以算的是某个变量的别名
如上图所示,该块空间的管理者可以是a、ra、rra。
2.引用的特性:
a.引用定义时必须初始化
b.一个变量可以多个引用
c.一旦引用一个实体,不再引用多个实体。也就是,引用后的对象变量是不可以修改的。
3.引用的意义:
a.做参数
之前写交换函数是通过传址实现的。
在学习引用后,可以引用传参。
此时可以视为函数的参数传实参的别名,即形参实参的地址相同,就可以直接在函数内部修改实参的。
b.做返回值
常见数据类型做返回值如图所示
引用做返回值
4.引用的好处
a.做参数好处:减少拷贝,提高效率;输出型参数,函数中修改形参,实参也修改了
?? 小问题:为什么会减少拷贝,提高效率
!! 回答:因为在交换函数中整型指针传参,会在交换函数的栈帧里创建空间存储形参,而交换函数中引用传参是不会开辟新的空间,直接在实参所在空间内部修改数值。
?? 小问题:为什么会函数中修改形参,实参也修改了
!! 回答: 在交换函数中引用做参数可视为函数的参数传实参的别名,即形参实参的地址相同,就可以直接在函数内部修改实参的。
b.做返回值好处:减少拷贝,提高效率;修改返回值
?? 小问题:为什么会减少拷贝,提高效率
!! 回答:让我们通过两个程序来进行讲解。
//画一个关于栈、堆、静态区的图
算是一个小彩蛋。在c语言的学习中,会遇到这样的题。利用const修饰字符指针str1和str2来接受存储在常量区唯一存在的“hello world"字符串。那么str1,str2存储的地址就是一致的。
利用常见的数据类型做返回值,如下图所示。在栈区开辟一块空间创建函数的栈帧,在函数的栈帧中一块空间用来存储返回值的数据。当函数调用结束,函数栈帧销毁,其所占据的空间使用权返回给计算机,其中的数据可能保持原值未被覆盖,可能被其他值覆盖,也有可能干脆销毁了。所以会创建临时变量(存储于寄存器)来临时拷贝返回值。
而引用返回,在满足前提条件的情况下。即使在函数栈帧销毁的情况下,仍然可以找到返回值变量n。函数返回的是返回值的别名,不需要在创建临时变量拷贝返回值的值,而是可以直接接受甚至是直接使用的。此时就减少了拷贝的次数,提高效率。
?? 小问题:怎样修改返回值呢?
!! 回答: 前提是出了函数作用域,返回变量(该变量存储在堆区、静态区)仍然存在,才能引用返回。
如图所示,Count()的返回值是静态变量n的别名。Count()=10,相当于Count函数的返回值是做10变化的。在输出的时候,再次调用Count(),会进入函数内部,静态变量n++。得到结果11。
如图,在利用常见的数据类型做返回值,是不可以直接修改函数的返回值。而是要创建相同数据类型的变量接受函数返回值,再对此变量进行修改。
5.const引用
a.权限-主函数内部
一般用引用做参数,const来修饰引用。引用、指针的权限是可以缩小的(const修饰表示可读不可看,是所限权限的),或者权限不变,也可以称为权限平移,但是权限是不可以放大的。(如图,b的权限是可读不可看,而rb的权限是可读且可看的,放大了引用的权限,是不可以的,编译器自然就进行了报错)
b.const引用用作缺省参数
函数参数如果想要实现传址调用,引用做参数时就不用const修饰。但是只是函数调用时需要用到参数的值,不进行修改,要用const加以修饰,缩小权限。
c.衍生知识:
double型变量d转换为int型,需要创建临时变量。而ri是临时变量的别名,临时变量是具有常量性的,所以ri前还需要加const作以修饰。
1.认识auto关键字
auto关键字可以自动推导变量的类型。
2.认识范围for遍历
我们常见的for循环遍历如图所示:
而c++中的范围for遍历如图所示