1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > C++入门:命名空间 缺省参数 函数重载 引用 内联函数 auto 范围for

C++入门:命名空间 缺省参数 函数重载 引用 内联函数 auto 范围for

时间:2020-11-21 11:28:07

相关推荐

C++入门:命名空间 缺省参数 函数重载 引用 内联函数 auto 范围for

这里写目录标题

前言命名空间缺省参数1、**什么是缺省参数**2、缺省参数的分类注意事项 函数重载1、形参不同2、形参顺序不同3、形参个数不同为什么会出现上述这样的情况呢??gcc上的函数修饰,只是简单取函数名g++上的函数名,通过_Z+函数名的长度+函数名+类型的首字母(按照参数顺序)g++上面的函数名修饰规则在加入类型之后,能够很好区分在函数名相同时,通过参数类型、顺序以及个数从而达到区分函数,注意!!函数返回值没有参与函数名修饰规则当中,所以不能用返回值来区分函数。 引用什么是引用怎么使用引用1、做参数2、做返回值 引用底层实现引用与指针的不同点 内联函数为什么会有内联函数内联函数使用内联函数的特性声明和定义分离时候的报错。 autoauto注意事项范围for

前言

从这边开始我们正式朝C++前进了。在C语言中有着许多不合理的地方或者是不舒服的地方,比如作用域、宏函数、指针等地方,于是C++在C语言的基础上进行调整,出现许多让我们程序猿舒服且比较好理解的地方。那我们就开始吧。

命名空间

在以前C语言的学习中,我们发现使用相同的名字来命名变量之类,会出现报错,这让我们很烦恼,这万一以后要是命名与库函数里面的东西重名,出现报错,难道我们需要找到写库的作者辩论辩论吗?凭什么就你用了那个名字之后我不能用呢,为了解决这个问题,于是C++引入了命名空间的概念:使用关键字 namespace 后面自己取个名字。例如:

namespace im{int rand = 9;//...}

接下来创好命名空间我们要怎么使用呢

有三种方式,这边我以std为例,原来标准库在引入命名空间之后也是被放到namespace std

指定作用域:std::cout;全局展开: using namespace std;部分展开:using std::cout;

缺省参数

1、什么是缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

void Func(int a = 0){int c = a + 5;}int main(){Func(); // 没有传参时,使用参数的默认值Func(10); // 传参时,使用指定的实参return 0;}

2、缺省参数的分类

缺省参数还分全缺省和半缺省

全缺省

void Func(int a = 10, int b = 20, int c = 30){//...}

半缺省

void Func(int a, int b = 20, int c = 30){//...}

注意事项

1、在半缺省中缺省值必须从右向左给,不能有隔着给。

下面是错误示范

void Func(int a = 10, int b , int c = 30){//...}

2、在定义和声明分离时,缺省参数只能放在声明,定义不用写。

函数重载

这是c++相比c语言很舒服的一个地方,支持在同一个作用域中有功能类似的同名函数,可以是形参类型不同或者顺序不同或者形参个数不同。

1、形参不同

int Add(int left, int right){cout << "int Add(int left, int right)" << endl;return left + right;}double Add(double left, double right){cout << "double Add(double left, double right)" << endl;return left + right;}

2、形参顺序不同

void f(int a, char b){cout << "int char" << endl;}void f(char b, int a){cout << "char int" << endl;}

3、形参个数不同

void func(){cout << "无参" << endl;}void func(int a){cout << "有参" << endl;}

为什么会出现上述这样的情况呢??

原因在于函数名修饰上面,这边由于因为vs上的函数名修饰规则比较复杂,不易观察,我用Linux上的gcc g++举例

gcc上的函数修饰,只是简单取函数名

g++上的函数名,通过_Z+函数名的长度+函数名+类型的首字母(按照参数顺序)

g++上面的函数名修饰规则在加入类型之后,能够很好区分在函数名相同时,通过参数类型、顺序以及个数从而达到区分函数,注意!!函数返回值没有参与函数名修饰规则当中,所以不能用返回值来区分函数。

引用

什么是引用

在语法上,引用可以理解为给变量取别名,实际代表的是变量本身。比如爱情公寓中的张伟,有各种小名,张益达、张大炮、snake,但无论叫哪个名字,都是指张伟这个人。在C++中 用&表示引用。通常加在类型后。

int i = 0;//类型& 引用变量名& = 引用实体int& j = i;

怎么使用引用

1、做参数

int Add(int& x, int& y){return x+y;}

2、做返回值

int m = 1;int& multi (){m *= 2;return m;}

这时候出现个问题,以下的代码可不可行

int& add(int x, int y){int sum = x + y;return sum; }

显然是不行的,因为sum是局部变量,出了作用域就销毁了还给操作系统,而引用是返回sum本身,这时候已经不属于你的,这时候你再使用这块空间是不安全,里面值可能没有改变,也可能改变了,取决于操作系统。

引用底层实现

刚刚接触引用,可能感觉挺神奇的,会拿其与指针对比,突然觉得c语言中的指针好麻烦,这个引用简单,且用起来很舒服。比如函数传指针的时候,你需要去解引用,而引用不需要传指针,直接修改。

//c语言版本void func1(int* pi){*pi = 4;}void func2(int& a){a = 5;}int main(){int i = 0;int* pi = &i;func1(pi);func2(i);return 0;}

让人惊奇的时候实现引用是通过指针实现。汇编指令完全相同,可以证明引用底层是通过指针实现的。

所以引用从本质来说,与指针没有什么差异,但是使用上比指针舒服很多,可以说是编译器帮你把这脏活给包揽了。

引用与指针的不同点

引用概念上定义一个变量的别名,指针存储一个变量地址。引用在定义时必须初始化,指针没有要求引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何 一个同类型实体没有NULL引用,但有NULL指针在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32 位平台下占4个字节)引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小有多级指针,但是没有多级引用访问实体方式不同,指针需要显式解引用,引用编译器自己处理引用比指针使用起来相对更安全

内联函数

为什么会有内联函数

在C语言中大家想必体会过宏函数的麻烦之处了吧,一不小心就容易出错

例如下面add宏函数,在x、y要加括号,在最外面还要加括号。一旦不小心少了一个括号,会出现不少问题。而且宏还有其他问题:

不能调试,只是单纯的替换。2. 没有类型检查。

因此为了代替宏,C++弄出了内联函数

#define Add(x, y) ((x)+(y))

内联函数使用

在函数前面加上inline关键字来修饰函数,在预处理阶段中对内联函数进行展开,而不是跟正常函数一样,在编译过程转换成call指令在链接的时候通过函数地址从而调用函数。

内联函数的特性

1、减少了栈帧的开销,文件空间增大,经典空间换时间,但是如果是递归之类的函数,或者过大的函数,使得消耗空间过大,编译器会忽略掉inline,当成正常函数来调用,所以对于编译器来说,inline只是一个建议而已。

2、内联函数声明和定义无法分离。

原因是在编译的时候内联函数已经展开了 声明定义分离之后 编译过程中只有函数声明 没办法展开 只能等待进入链接环节 拿着修饰过的函数名 需要去符号表找相应地址 进行链接 而内联函数地址不会进到函数表里 会出现链接失败的情况

声明和定义分离时候的报错。

auto

在C语言中,如果一个类型太长,我们一般需要采取typedef 缩短类型长度,例如typedef struct ListNode LNode, 而在C++当中,则是弄出了auto,是一个自动推导变量类型的"占位符",原因是编译器在编译时候就将其替换掉,因此他不是类型声明,相当于占位,把这个活交给编译器来干。程序猿使用的时候方便很多,但不是十全十美的,会使可读性下降,不好理解该变量的类型。

auto注意事项

1、用auto声明的变量必须初始化,因为编译器通过初始化的值从而推导该变量的类型。

2、形参无法推导类型。

3、不能推导数组类型。

4、auto* 与 auto没有区别,但是引用的话必须要需要在后面加上&

5、在同一行声明多个变量需要保证全部变量是同一类型。

范围for

在C语言当中,我们遍历数组之类的,需要for循环来遍历,需要确定从什么时候开始,不满足什么条件时候停止,有时候在确定范围上容易出错,在C++11引入一个范围for,也叫语法糖,使用方法如下

int arr[]={1,2,3,4,5,6};for(auto a:arr){//...这里与for循环一样使用}

可以用continue,break进行操作。

范围是确定的,否则会出现问题。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。