1.引用的概念引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用同一块内存空间。2.引用的格式类型 引用变量名 ( 对象名 ) 引用实体举例如下注意引用类型必须和引用实体是同种类型的3.引用的特性(1). 引用在 定义时必须初始化例如int d; 这样就是没有初始化是错的(2). 一个变量可以有多个引用int a 10;int b a;int c b;int* p b; //p是指针(3). 引用一旦引用一个实体再不能引用其他实体4.取别名原则对原引用变量权限只能缩小即 可读可写(普通类型) 可以改成 只读(const)不能放大:即 只读 不能改成 可读可写的例子1权限的放大不能把const给非const例子2权限的缩小 非const 既可以给非const也可以给const例子3权限缩小和放大规则:适用于引用和指针间例子4 权限不适用于普通赋值:难点隐式类型转换的引用整形e能否做双精度浮点型d的别名呢直接赋值是不行的需要加上const才正确。即const int e d;正确解释隐式类型转换的普通赋值的情况上面的例子int fd从语法上看把8字节的d不能直接给4字节的f因为浮点数和整形的存储形式就不一样没办法直接截取所以d需要先把整数部分给一个4字节的临时变量再把临时变量给f再看引用int ed;临时变量具有常性所以这里把临时变量给引用e的时候相当于是把自带const的临时变量赋值给非const的e把只读的给可读可写的是放大了权限所以错误必须改成const int ed;才正确5.引用的使用场景做参数(1)传参:实参给形参传值和传地址都需要传一份值/地址的拷贝引用传参可以减少拷贝提高效率1234567891011121314151617181920voidSwap(int x,int y){inttmp x;x y;y tmp;}voidSwap(double x,double y){doubletmp x;x y;y tmp;}intmain(){inta 0, b 1;swap(a, b);doublec 1.1, d 2.2;swap(c, d);return0;}(2)作输出型参数leetcode上的题往往有输出型参数在c中就可以用引用代替更加方便做返回值intCount()的讲解传值返回:会有一个拷贝传引用返回:没有这个拷贝了函数返回的直接就是返回变量的别名1234567891011int Count(){intn 0;n;returnn;}intmain(){intret Count();return0;}首先我们来看普通的传值返回普通的传值返回需要把返回值n给一个函数类型int的临时变量(函数类型就是返回值类型)再把临时变量给ret。为什么设计一个临时变量直接把n给ret不行吗答不行因为当函数Count里执行完各种代码后返回n等出了Count函数的作用域后n就会销毁所以不能直接把n给ret需要一个临时变量。如何证明返回时存在临时变量呢如果你用int ret 接收写成int ret Count();发现无法运行因为临时变量有常性所以需要写成const int ret Count();才能通过。此时再看传引用返回当用引用接收引用返回时这里ret和n的地址一样也就意味着ret其实就是n的别名。但是因为n出作用域不会立即被覆盖所以第一次通过ret可以打印是1当打印第二次时因为前面已经调用过一次打印函数已 销毁 的Count函数栈帧在此时被打印函数覆盖再打印ret就会是随机数了即如果函数返回时出了函数作用域如果返回对象还未还给系统则可以使用引用返回如果已 经还给系统了则必须使用传值返回。用static修饰n后用static静态变量使n只初始化一次且改变其生命周期把n放进了静态区这样n就一直存在就可以通过ret找到n了再怎么打印ret都是1.传值传引用效率比较以值作为参数或者返回值类型在传参和返回期间函数不会直接传递实参或者将变量本身直接返回而是传递实参或者返回变量的一份临时的拷贝因此用值作为参数或者返回值类型效率是非常低下的尤其是 当参数或者返回值类型非常大时效率就更低。 总结传值和指针在作为传参以及返回值类型上效率相差很大 。
C++详细分析讲解引用的概念与使用
1.引用的概念引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用同一块内存空间。2.引用的格式类型 引用变量名 ( 对象名 ) 引用实体举例如下注意引用类型必须和引用实体是同种类型的3.引用的特性(1). 引用在 定义时必须初始化例如int d; 这样就是没有初始化是错的(2). 一个变量可以有多个引用int a 10;int b a;int c b;int* p b; //p是指针(3). 引用一旦引用一个实体再不能引用其他实体4.取别名原则对原引用变量权限只能缩小即 可读可写(普通类型) 可以改成 只读(const)不能放大:即 只读 不能改成 可读可写的例子1权限的放大不能把const给非const例子2权限的缩小 非const 既可以给非const也可以给const例子3权限缩小和放大规则:适用于引用和指针间例子4 权限不适用于普通赋值:难点隐式类型转换的引用整形e能否做双精度浮点型d的别名呢直接赋值是不行的需要加上const才正确。即const int e d;正确解释隐式类型转换的普通赋值的情况上面的例子int fd从语法上看把8字节的d不能直接给4字节的f因为浮点数和整形的存储形式就不一样没办法直接截取所以d需要先把整数部分给一个4字节的临时变量再把临时变量给f再看引用int ed;临时变量具有常性所以这里把临时变量给引用e的时候相当于是把自带const的临时变量赋值给非const的e把只读的给可读可写的是放大了权限所以错误必须改成const int ed;才正确5.引用的使用场景做参数(1)传参:实参给形参传值和传地址都需要传一份值/地址的拷贝引用传参可以减少拷贝提高效率1234567891011121314151617181920voidSwap(int x,int y){inttmp x;x y;y tmp;}voidSwap(double x,double y){doubletmp x;x y;y tmp;}intmain(){inta 0, b 1;swap(a, b);doublec 1.1, d 2.2;swap(c, d);return0;}(2)作输出型参数leetcode上的题往往有输出型参数在c中就可以用引用代替更加方便做返回值intCount()的讲解传值返回:会有一个拷贝传引用返回:没有这个拷贝了函数返回的直接就是返回变量的别名1234567891011int Count(){intn 0;n;returnn;}intmain(){intret Count();return0;}首先我们来看普通的传值返回普通的传值返回需要把返回值n给一个函数类型int的临时变量(函数类型就是返回值类型)再把临时变量给ret。为什么设计一个临时变量直接把n给ret不行吗答不行因为当函数Count里执行完各种代码后返回n等出了Count函数的作用域后n就会销毁所以不能直接把n给ret需要一个临时变量。如何证明返回时存在临时变量呢如果你用int ret 接收写成int ret Count();发现无法运行因为临时变量有常性所以需要写成const int ret Count();才能通过。此时再看传引用返回当用引用接收引用返回时这里ret和n的地址一样也就意味着ret其实就是n的别名。但是因为n出作用域不会立即被覆盖所以第一次通过ret可以打印是1当打印第二次时因为前面已经调用过一次打印函数已 销毁 的Count函数栈帧在此时被打印函数覆盖再打印ret就会是随机数了即如果函数返回时出了函数作用域如果返回对象还未还给系统则可以使用引用返回如果已 经还给系统了则必须使用传值返回。用static修饰n后用static静态变量使n只初始化一次且改变其生命周期把n放进了静态区这样n就一直存在就可以通过ret找到n了再怎么打印ret都是1.传值传引用效率比较以值作为参数或者返回值类型在传参和返回期间函数不会直接传递实参或者将变量本身直接返回而是传递实参或者返回变量的一份临时的拷贝因此用值作为参数或者返回值类型效率是非常低下的尤其是 当参数或者返回值类型非常大时效率就更低。 总结传值和指针在作为传参以及返回值类型上效率相差很大 。