今天开起C++大门,C++对C语言的许多缺陷进行了改进,但是总是会存在一些未知的问题,等着我们共同努力去发现解决。C++是一个不断发展改进的过程,它的魅力也是居高不下。在排行榜中基本紧跟老大哥C语言的步伐。哈哈
今天来说说C++一些基础共有十一大部分
一、C语言标准中共规定了32个关键字,我们知道这些关键字在编程时是多么重要。同样在C++98中有63个关键字。为我们准备进军C++。
二、接下来我们来说说命名空间,这也是C++继承C语言新添加的语法namespace
之所以要引进命名空间就是因为当一个项目有很多源文件一起运行时会产生命名冲突的问题。所以每个源文件都可以定义自己的命名空间,然后在自己命名空间中定义成员变量和成员函数,就不会产生重定义的问题。就好比在我们这个地球村有许多和我们重名的人,那我们怎么区分呢?对了就是进行划分区域再划分,分治的思想哈哈。可以吧一个项目比作地球,重定义的成员就像我们名字一样的人,命名空间就像这些国家,省市一样。
1.来说说命名空间的定义:
分为3种:①普通命名空间 ②嵌套命名空间(就像省里面嵌套市一样) ③同一个文件中可以定义多个相同的命名空间,但编译器会把他们合成一个
2.命名空间的三种使用方式:
①:假如命名空间中的成员被偶尔用到时就可以这样使用 命名空间名称::成员
②:如果命名空间中的某个成员被多次用到那就可以使用这一条语句 using 命名空间名::成员,后面使用就不用了特意说明,直接使用,此时该成员就像一个文件的全局变量,缺点:可能会和其它成员冲突
③:如果命名空间的多个成员被多次使用,可以这样使用:using namespace 命名空间名; 就像经常用的using namespace std;它的成员会被全部展开,相当于全局变量,冲突率就更高了
三、就是C++的输入输出了cin和cout
要说C++的输入输出之前先来说说C语言的输入输出
scanf这个函数在对其变量赋值时必须对其取地址,如果不取地址,不会在编译时崩溃,它在程序运行时崩溃,这一点真的很可恶哈哈(不取地址,VS编译器就会默认拿第一个地址来赋值,那是不可访问的当然崩溃),再来说说printf这个函数,它不会对参数进行匹配性检测printf("%d,%lf\n", 10, "hehe");显然这是不合理的,另外C的输入输出语句格式需要记得很准,不然呵呵。
基于以上这样所以C++引入cin和cout 它使用简单,不用考虑格式并且支持连续的输入输出。
另外C语言函数:①若无函数返回类型时,它会默认为整形。②函数没有参数时,在传参依旧会压栈只是不会用罢了。C++都改进了这种缺陷。
四、缺省参数
①:什么是缺省参数呢?
全省参数就是声明或定义函数时为函数的参数设定一个默认值,当进行函数调用时如果不传参就会使用这个默认值,有点像备胎的意思哈。说完缺省参数的概念来说说它的分类
②:缺省参数的分类:它分为①:全缺省参数②半缺省参数
其中全缺省参数就是函数的所有参数就会设定一个默认值,版缺省就是函数的参数只有一部分有默认值。
注意:1.半缺省的函数的参数默认值只能从右往左给,不能间隔这给。必须连续
2.全省参数只能在函数定义或声明给一个,不能两个同时给。(如果都设定,编译器不知道用哪个)一般给在声明。why?一般函数定义会包含在文件中可能不会看见它的实现自然也就不知道它有没有缺省参数并且是什么。
3.缺省参数的赋予:1.可以是一个常量2.可以用全局变量来提供。但是不能赋表达式,因为值不确定。
4.C语言不支持缺省参数的设定
五、说完缺省参数来述说函数重载
1.概念:就是多个函数拥有同一个函数名但实现不同的功能,重载的函数参数列表必须不同
2.条件:要想构成函数重载就必须满足这几种条件①:同一个作用域(都是全局作用域或命名空间)。②:函数名相同。
③:参数列表不同指的是参数的类型不同或者参数个数不同或者参数类型的顺序不同
3.原因:之所以C++中能存在函数重载,是因为编译器在编译期间会对函数的参数类型进行推演,并根据推演结果来决定调用哪一个函数。如果没有合适的类型匹配的重载函数就可能会产生两种做法:①:尝试进行隐式类型转换--直接调用 ②:编译失败:存在两种级以上转换方式。
注意:①:全缺省和无参的重载函数最好不要同时存在,当调用函数不给参数时会产生两种调用的方式,出错。
②:C语言不支持函数重载,因为名字修饰规则不同。
③:仅仅函数返回值不同不会构成函数重载,因为调用时可能会不唯一。VS把返回值类型也加进去在此不是很科学。
六、extern登场
如果我们再一个C++程序中需要运行一部分C语言程序那该怎么办呢?这是extern就上场了,只需要在所需要运行的C语言程序前加上extern "C"就可以了
七、引用
1.现在来说说引用的概念:引用就是给一个变量取一个别名,编译器不会为引用变量开辟内存,它和引用的变量共用一块内存区域(定义概念上)
2.如何定义格式?引用变量的类型后面紧跟& 接着引用变量的名字 = 引用的变量
3.引用的性质:①:引用在定义时必须初始化
②:一个实体可以有多个引用
③:一个引用变量和实体结合后,就不能和其他实体结合。
④:引用类型必须和实体类型相同
注意:实体的生命周期一般比引用周期长
4.const类型的引用
①参数列表:能传递引用尽量传递引用
②参数按照引用的方式:传参数---传值一样 函数体中对形参的操作与传值格式可以达到与指针类型的效果
1.const引用
double c = 16.6; const int& rc = c; 此时rc不再是c的引用,而是将c的整数部分拿出来重新找一块空间放进去,用ra来指向它,由于这是编译器自己做的,此刻该块空间就存着一个临时变量,我们又无法得知该空间的地址,又无法得知它的名字。具有常性所以它无法改变,所以加const。
在C++中,const类型的引用---万能引用(既可以引用普通类型的变量也可以引用常量)
5.引用的应用:
①.函数的参数:如果需要通过形参改变外部的实参---普通类型
如果不需要通过形参改变外部的实参---const类型的引用
②:返回值:返回实体的声明周期比函数的声明周期长
注意:不能返回栈上的空间
6.参数类型:
先来说说函数调用传值和传址的优缺点
①传值:优点:不会通过函数形参来改变实参 缺点:不能改变实参,传参开销大
传值:优点:传参开销小,并且可以通过形参来改变实参。 缺点:容易忽略指针判空,格式较为复杂(第一次接触指针总想去掉*哈哈)
②:传值效率最低,传地址&传引用 效率基本一样,因为底层处理指针和引用一样
③:在底层:
编译器在底层将引用按照指针的方式来进行处理的,引用实际就是指针。
T& ===> T* const (指向变量的内容可改,指向的变量不能改)
const T& ===> const T* const (所指变量和其内容都不能改)
在底层,引用变量实际是有空间的。
7.栈帧与栈有什么区别?
①: 栈帧是利用栈的特性的一块内存空间。栈则是一种特殊的数据结构
②:调用约定(_cdecl):就是约定传参的顺序以及传参机制,传参压栈方式和函数接收参数进栈方式
8.指针和引用有什么区别?
①:引用在定义时要初始化,指针可以不用。
②:没有空引用但有空指针
③:一个引用只能引用一个实体,而指针可以指向其他
④:有多级指针但没有多级引用
⑤:在sizeof中,引用为引用类型大小,而指针始终地址空间多占字节数
⑥:引用加1是实体加1,指针加1是内存区域往后移动一个
⑦:访问实体方式不同:指针显示解引用,引用编译器自己处理
⑧:引用比指针用起来更安全
八、内联函数:
1.inline修饰的函数就是内联函数
2.内联函数处理:在编译器编译阶段,用函数体替换函数调用的位置,少了函数调用参数压栈以及栈帧创建的时间开销,提高了代码的运行效率
3.注意:①加inline不一定当内联函数来处理,没有循环,递归,才可能当成内联函数来处理(不同编译器处理不同)
②使用内联函数不能使声明和定义分开,否则会产生链接错误
4.对比宏与const
①:const修饰的常量,具有宏常量替换的特性
②:宏替换发生在预处理阶段,const修饰的变量替换发生在编译阶段
宏函数:
①:优点:①提高代码运行效率--在预处理阶段:用宏函数体替换调用位置,没有函数调用开销
②:缺点:①在预处理阶段进行替换,不会进行参数类型检测
②代码的复用性不好,代码膨胀。
③无法调试
④有副作用(括号严格使用,最好所有变量都加括号,每一部分也要加括号。即便如此也可能会有副作用就是遇到类似(++b这种,一旦宏中替换后有多个就会导致b被多次计算)
内联函数:①在编译阶段进行替换,会进行参数类型检测
②无宏的副作用
九、auto关键字(C++11)
1.概念:现今:根据赋值的类型来判断变量的类型(类型占位符)由于这个特性必须初始化
早期:在C中auto修饰的变量,是具有自动存储器的局部变量
2.使用规则:
①:auto 声明指针类型加不加*都一样
②:auto 声明引用则一定要&
③:声明多个变量类型必须一样
④:不能作为函数参数(带缺省值也不行)
⑤:不能推演数组
3.优点:简化代码
十、基于范围的for循环(C++11)
1.出现原因:for对于一个确定数组范围,还要给定显得多余,还容易出错
2.条件:①范围必须确定
②迭代对象实现++或==操作
3.注意:范围for注意是将数组元素拷贝到临时变量e中
十一、指针空值nullptr(C++11)
1.原因:由于NULL是一个宏,定义为整数0,或者被定义为无类型指针(void*)的常量,可能会遇到不必要的麻烦
2.nullptr代表一个指针空值常量。
3.nullptr的类型为nullptr_t
4.注意:①使用nullptr不用包含头文件,c++将其引为关键字
②:sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同
③:为了提高代码的健壮性,在表示指针空值时最好使用nullptr。
珍&源码