前沿:
c++作为目前比较的流行的语言之一,在就业上也是运用比较广泛的语言之一,并且经过这么多年的历练久经不衰,所以说选择学c++是一个不错的选择^_^,前面看到一个段子,如何在21天精通c++,我动态里有这张图片,一个努力的程序员经过几年的磨练也只能说是熟悉c++,对于语言的学习并不可能有速成班,都是不断的积累,c++也是如此,但相比较c语言,c++的语法特性繁琐复杂,知识点比较琐碎,它是对c语言一些缺陷的完善,并且保留c语言的所有特性,也就是c语言能用的在c++中也能实现,在学习过程中,一定要做好总结和思维导图的构建,把每个知识进行良好的串联在一起,才能熟悉的运用它,而本篇博客也只是初步的认识一下c++,只能让你浅浅的进入新手村。
思维导图:
目录
一、命名空间:
1.1命名空间存在的意义:
1.2命名空间的定义:
1.3命名空间的使用:
二、c++的输入与输出:
2.1第一个c++函数:
2.2c++的输入与输出:
三、缺省参数:
3.1缺省参数的定义:
3.2省参数的分类:
四、函数重载:
4.1函数重载的意义:
4.2函数重载的概念:
4.3函数重载的列举:
五、引用:
5.1引用的概念:
5.2引用的特性:
5.3引用的应用:
5.5引用和指针的区别:
六、内联函数:
6.1内敛函数存在的意义:
6.2内敛函数的定义:
6.3内敛函数特性:
总结:
一、命名空间:
1.1命名空间存在的意义:
1.1.1要知道c++是对c语言缺点的完善,而在c语言中我们是知道,定义变量、函数名或者全域名是不能相同的,否则会产生冲突,但要知道这都是大量存在的,就像一个名字也有很多重名,一个项目,每个人负责不同的模块,也避免不了名字相同(因为我不知道你也用了这个名字),在c语言中就会产生冲突,而且在全域中也可能和库函数中名字相同例如:
#include<stdio.h> #include<stdlib.h> int rand=10;//编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数 int main(){ printf("%d\n",rand); return 0;}
这里编译错误在c语言中就是没办法避免的,所以c语言编译就要避免和c语言库里函数名相同,这是很麻烦的,要知道我们并不能知道所有库函数,而c++命名空间的存在就解决了这个问题。
1.2命名空间的定义:
1.2.1命名空间的定义要用到一个关键字就是namespace加命名空间的名字,然后接一个{ },里面就是命名空间的成员。
//这我定义的名字为xiaomanamespace xiaoma{ //可以定义变量也可以定义函数 int rand =10; int Add(int x,int y) { return x+y; } //同时也可以进行嵌套 namespace hello{ //嵌套在命名空间xiaoma的命名空间hello //不同命名空间里的名字可以相同 int rand=20; int Add(int x,int y) { return x+Y; } }}
1.3命名空间的使用:
1.3.1命名空间中的成员并不能直接使用,有三种形式使用方式:
<1>加命名空间名称以及作用域符号:
namespace xiaoma{ int a=10; int b=20;}int main(){ // printf("%d\n",a) 这种是错误的不能直接使用 printf("%d\n",xiaoma::a); printf("%d\n",xiaoma::b); return 0;}
<2>使用using将命名空间某个成员引入:
namespace xiaoma{ int a=10; int b=20;}usinng xiaoma::a;int main(){ // printf("%d\n",a) 这种是错误的不能直接使用 printf("%d\n",a); //这个已经被引入了所以可以直接用 printf("%d\n",xiaoma::b); return 0;}
<3>使用using namespace命名空间的引入
namespace xiaoma{ int a=10; int b=20;}usinng namespace xiaoma;int main(){ printf("%d\n",a); printf("%d\n",b); return 0;}
二、c++的输入与输出:
2.1第一个c++函数:
2.1.1就像学习c语言一样,我们学习c++也们也来写第一个c++函数。
#include<iostream>using namespace std;int main(){ cout<<"Hello World"<<endl; //endl表示换行的意思 return 0;}
2.2c++的输入与输出:
#include<iostream>using namespace std;int main(){ int a; double b; char c; //可以自动识别变量类型 cin>>a; cin>>b>>c; cout<<a<<endl; cout<<b<<' '<<c<<endl; return 0;}
2.2.1cout(输出)和cin (输入)的使用必须包含头文件<iostream>和以及按命名空间使用方法使用std.
2.2.2<<是流插入运算符,>>是流提取运算符。 2.2.3std是C++标准库的命名空间,怎么理解呢?他就好比一个围墙,把标准库全放放在里面,而我们要访问,就需要透过围墙来进行访问。三、缺省参数:
3.1缺省参数的定义:
3.1.1缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实,参则采用该形参的缺省值,否则使用指定的实参。
#include<iostream>using namespace std;int Add(int x=10,int y=20){ return x+y;}int main(){ int ret1=Add(); //不穿参数,使用形参默认值 cout<<ret1<<endl; int ret2=Add(1,2) //穿参数,使用指定实参 cout<<ret2<<endl; return 0;}
3.2省参数的分类:
3.2.1全缺省参数:
#include<iostream>using namespace std;int Add(int x=10,int y=20,int z=30){ return x+y+z;}int main(){ int ret1=Add(); //可以不传参数 int ret2=Add(1); //可以传一个参数 int ret3=Add(1,2); //可以传两个参数 int ret4=Add(1,2,3); //可以传三个参数 //但不能像Add(,2,3)或者这样Add(1,,3)传参,必须是从左到右连续滴传参。 cout<<ret1<<endl<<ret2<<endl<<ret3<<endl<<ret4<<endl;}
3.2.2半省参数:
#include<iostream>using namespace std;int Add(int x,int y=20,int z=30){ return x+y+z;} //半省参数必须从右向左依次赋值int Add1(int x,int y,int z=30){ return x+y+z;}//上面两种都是可以的//但不能中间间隔例如:int Add(int x=10,int y,int z=30)//或者这样也是不行的 int Add(int x=10,int y,int z)int main(){ int ret1=Add(1,2,3);//可以 int ret2=Add(1,2);//可以 int ret3=Add(1);//可以 // int ret4=Add(); 不可以的x需要传参同样滴 int ret5 =Add1(1,2,3);//可以 int ret6=Add(1,2);//可以 // int ret7=Add(1); 不可以因为y没有传参 //半缺省参数是要赋值的 return 0;}
四、函数重载:
4.1函数重载的意义:
4.1.1在日常生活中我们也经常遇到一个词表达不同的意思,例如中国的体育项目的两大极端:
乒乓球和足球一个是“谁也赢不了”另一个也是“谁也赢不了”相同的词表达这不同的意思,c++中的重载也在此体现来。
4.2函数重载的概念:
4.2.1是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这
些同名函数的形参列表(参数个数或类型或类型顺序)不同,常用来处理实现功能类似数据类型 不同的问题。4.3函数重载的列举:
#include<iostream>using namespace std;int Add(int x,int y,int z){ return x+y+z;}//参数个数不同int Add(int x,int y){ return x+y;}//参数类型不同double Add(double x,double y){ return x+y;}//参数顺序不同double Add(int x,double y){ return x+y;}double Add(double y, int x){ return x+y;}int main(){ int ret =Add(1,2,3); int ret1=Add(1,2); double ret2=Add(1.2,2.2); double ret3=Add(1,1.2); double ret4=Add(1.2,1); //函数重载的作用就是一个函数可以实行多种功能 cout<<ret<<endl<<ret1<<endl<<ret2<<endl<<ret3<<endl<<ret4<<endl; return 0;}
五、引用:
5.1引用的概念:
5.1.1引用比较好理解啦,就是给你原有的变量去了一个别名,例如在生活中你的外号,就像叫我小马一样都是别名的意思,编译器不会给引用变量开辟新的内存,他和他引用的变量公用同一个内存空间。
#include<iostream>using namespace std;int main(){ int a=10; int& ra=a; printf("%p\n",&a); //打印a的地址 printf("%p\n",&ra); //打印ra的地址 两个地址是相同的 return 0;}
5.2引用的特性:
<1>引用变量必须初始化。 就像你给一个人起小名要有对象呀
<2>一个变量可以有多个引用。 一个人可以有多个外号什么的
<3>引用一旦引用一个实体,再也不能引用其他实体。
#include<iostream>using namespace std;int main(){ int a=10; int&ra=a; //这是引用的初始化 // int&ra; //这里没有初始化是不正确的。 int& rb=a; //一个变量可以有多个引用 return 0;}
5.3引用的应用:
5.3.1引用做参数:
通过引用的概念我们可以知道引用是和他的引用变量用同一个地址,所以改变引用就是改变他所引用的变量,就像夸小马文章写的好不就是在夸我吗^ _ ^。
#include<iostream>using namespace std;void swap(int& x,int& y){ int tmp=0; tmp=x; x=y; y=tmp;}int main(){ int x=10; int y=20; swap(x,y); cout<<x<<' '<<y<<endl; return 0;}
5.3.2引用做返回值:
#include<iostream>using namespace std;int& Add(int x,int y){ static int ret=x+y; //想想这里为什么用static return ret;}int main(){ int ret=Add(1,2); cout<<ret<<endl; return 0;}
在这里我们想一下为什么要用static 要是不用static的后果是什么呢? 在我们讲函数栈帧的创建和销毁的时候已经知道,局部变量是储存在栈区的,而栈区是随着函数调用结束后是会被销毁的, 但引用是和引用对象一个地址的,static是把局部变量从栈区存放到静态区,这样随着函数的调用结束后不会被销毁,因此返回的时候还能够找到,要是不用static当返回去寻找的时候是找到的就会是随机值。就好比你住个酒店,而当你退房了之后,发现你的包裹没有拿,而当你返回去的时候,你就无法确定你的包裹还在,他可能还在就是没有被收拾,但有可能你住的酒店已经被其他用户住给扔掉了,这都是有可能的,而static就是把包放在一个储存的东西的地方,你再去这个地方拿就行了。
5.5引用和指针的区别:
5.5.1引用就是引用对象的一个别名,而指针是变量的地址/
5.5.2引用必须初始化,而地址不需要初始化。
5.5.3引用在初始化一个引用对象后就不能在引用其他变量了,而指针确可以在任何时候指向同类型的地址。
5.5.4引用自身加一是引用对象加一,而指针加一则是地址加一。
5.5.5指针有多级指针,而引用没有
六、内联函数:
6.1内敛函数存在的意义:
在c语言中调用一个函数要经过栈帧的创建和销毁,而当一个函数调用次数过多的时候就会降低程序运行的效率。这里的解决办法是什么呢?在c语言中有一个解决的方法就是宏函数。想必大家也忘了宏函数的写法了,这里我写一个宏函数的代码。
#include<iostream>using namespace std;#define Add(x,y) ((x)+(y))int main(){ int ret=Add(1,2); cout<<ret<<endl; return 0;}
为什么宏函数解决了效率呢,要知道一个程序运行的完整运行,是有预处理,编译,汇编,链接四个过程的,而宏函数是在预处理已经完成了。但宏函数已经解决了c栈帧创建和销毁的缺点,为什c++还会创建一个内敛函数呢?要知道虽然宏函数解决了效率问题,但它本身也有自身的缺点,我们可以看出宏函数还是很容易写错的,我这个是比较简单的,要是复杂一点就是很容易就写错的,而宏函数因为在预处理就已经结束了,所以是没有办法调试的,并且他也没有类型安全的检查,因此c++就用内敛函数来解决这个问题。
6.2内敛函数的定义:
6.2.1以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。#include<iostream>using namespace std;inline int Add(int x,int y){ return x+y;}int main(){ int ret =Add(1,2); cout<<ret<<endl; return 0;}
内敛函数和普通函数功能相同就是在函数inline同时也具有了宏函数的一些功能就是不参与编译,在预处理就已经完成了。
6.3内敛函数特性:
6.3.1 inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会 用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运 行效率。 6.3.2 inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建 议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不 是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。 6.3.3 inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址 了,链接就会找不到总结:
对于这篇文章讲的只是让我们初步的了解认识c++语言,就相当于进入一个新手村才刚刚开始,而c++的脊髓还在后面,就是c++引入类的概念,使c语言的面对过程变为了面对对象,这才是c++魅力所在,而这篇文章让我们可能看的懂一点点简单的c++文章,但浅浅的总结小马也写了5000+字数,对于一些东西还是栈帧的理解深度,所以对于栈帧不理解的伙伴一定要认真看看栈帧,我前篇的文章哈哈哈哈,还有一定要注重思维导图和总结!!
^_^最后小马码文不易,如果觉得文章有帮助的可以点赞关注,希望我们一同学习,共同进步!!!