cpp基础(2)

cpp基础(2)

引用

概念与特性

举个例子先,一个人可以有很多别名,比如catjuicy又名猫汁、猫老菩萨、猫大左等等,如果在大街上喊这些名字,都会说同一个人来回应。因此,cpp开启了一个全新的概念:引用(cite) ,使用方法如下:

void test()
{
   int m = 0;
   int& z = m;
}

z便是引用类型,意味着z是m的别名,他们是一体的,引用类型也必须和引用的实体是同种类型的。

如果此时对z进行修改,m和z的值都会被同时修改,因为他们是一样的,连地址都是相同的,这与c中的指针类型很像但是不完全一样,因为引用更浅显易懂,而且方便使用。

此外,引用时有3点要注意:
1.引用在定义时必须初始化
2.一个变量可以有多个引用
3.引用一旦引用一个实体,就不可以引用其他实体

常引用

老样子,举个例子先:

void test()
{
   const int m = 1;
   //int& rm = m; //不可以
   const int& rm =m;//可以

   //int& rz = 96; //不可以
   const int& rz =96;//可以

   double d =6.4;
   //int& rd =d; //不可以
   const int& rd = d;//可以
}

下面来做解释,引用的范围只可以缩小不可以扩大。
第一个,因为m是const只读类型的,所以m不可以是int&的引用,因为int&是既可以读又可以写,属于范围扩大,所以只可以使用同种const只读类型的引用;
第二个,因为96是一个常数,是不可以修改的,同样也只可以使用const只读类型的引用来引用96;
第三个,因为double是八字节类型的,而且存储方式和整形int类型天差地别,但是有人会问了,double a = 8.8; int b = a;这个算什么呢,其实,a会先创造出一个int的整形临时变量,把整型值赋予到这个临时变量中,b再等于这个临时变量。不用想,这个int整形临时变量肯定也是只读的,因此,可以使用const只读引用来引用。

使用场景

讲了这么多,相信有慧根的各位已经想到了引用的用法:
1. 作为函数参数
2. 作为函数的返回值

没错,正是这样,举两个例子先:

void swap(int& a, int& b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

and

int& count()
{
    static int n = 0;
    n++;
    return n; 
}

第一个如图所示,放弃了传统的指针类型,而是采用引用便可以达到和指针一样的效果。
第二个如图所示,但是注意n一定要设置为static全局变量,不然出了栈帧n会销毁,因此如果再次调用其他函数会导致函数返回值变成随机值。所以:如果函数返回时,出了函数作用域,如果返回对象未返还给系统,则可以使用引用返回,如果已经还给系统了,那么必须使用传值返回。

效率

如大家所想,参数传引用和传值效率相比,传引用必然更快,因为地址都相同,不会重复创建新的临时变量,自然快人一步;
同时,函数返回值使用引用or值返回自然效率也会不同,与上面同理;
但是,传引用和传指针,函数返回值返回引用和指针,二者效率相差不多,因为底层原理都相似。

引用与指针的区别

在语法层面,引用只是一个别名,不会独立开辟空间,而是和原本的实体共用一块空间,但是仔细一想,这怎么可能呢,创造一个新变量怎么会电脑会没有变化呢?当然,下面来从底层实现来解释一下:
在底层逻辑中,引用和开辟新指针的汇编代码是完全一样的,这意味着,其实引用本质和指针就是同一种操作,只不过是cpp的创始人为了理解更方便而创造出的概念,但是底层实现还是一模一样的,(感觉像cpp创始人给开辟指针来了一个引用)。
当然,也是使用方面肯定有区别的,区别如下:
在这里插入图片描述

内联函数

相信在c中,大家都记得宏定义(define) , 当然,我来简单写一个宏定义的add函数好了,#define ADD(a, b) ((a)+(b)),肯定会有人说,这么多的括号甚是麻烦,还要注意很多细节,有没有别的办法呢?
当然!cpp设置了全新的内联函数,只需要在函数定义or声明前加一句online,便可以轻松实现和宏定义类似的功能,举个例子先:

inline int ADD(int a , int b)
{
     return a+b;
}

开始介绍,inline对于编译器只是一个建议,如果函数过长 (一般编译器会认为10行以上算长) 或者函数内部有循环or递归时,编译器便会不采用像宏定义一样直接展开,而是在程序编译时的链接环节时调用函数地址从而调用函数,这是很聪明的做法。

inline和宏定义一样,都是以空间换时间,省去调用函数额外的开销,但是inline不可以声明和定义相分离,举个例子:如果有一个add.h和add.cpp的话,add.h写函数声明但是add.cpp写函数的定义。
那么,不管inline写在那个文件里面,在test.cpp中整体的函数都是运行不了的,原因是如果inline的话函数不会生成地址,那么在编译的链接环节时根本找不到相关的函数。当然了,如果非要写的话,只能写在add.h中,因为在编译中的预编译阶段中会将add.h这些头文件展开,这样才可以看到内联函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值