C++编程学习(十)引用
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。
注意以下几点与指针的区别:
- 不存在空引用。引用必须连接到一块合法的内存。
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
- 引用必须在创建时被初始化。指针可以在任何时间被初始化。
1、把引用作为函数参数传递
先看以下内容:
#include <iostream>
using namespace std; // 函数定义
void swap(int x, int y)
{
int temp;
temp = x; /* 保存地址 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 x 赋值给 y */ return;
} int main ()
{
// 局部变量声明
int a = ;
int b = ; cout << "交换前,a 的值:" << a << endl;
cout << "交换前,b 的值:" << b << endl; /* 调用函数来交换值 */
swap(a, b); cout << "交换后,a 的值:" << a << endl;
cout << "交换后,b 的值:" << b << endl; return ;
}
这时候a、b交换前后的值不变,为什么明明调用了swap()函数,a b的值却没有变化?那就需要了解以下几点:
(1、在函数定义中,x,y是形参,声明时不占用内存,只有将实参值赋给形参时才会给出内存空间。
(2、在函数体中,修改形参的任何参数,都触及不到实参。形参接收到实参的值后,马上就会与实参毫无联系。也就是说:
比如上面的例程中,a=100,b=200 。调用swap()函数后,x=100,y=200(a b传值给x y后就和他们毫无联系了),这时候在swap()函数中,x y完成数值交换。但是已经和a b毫无关系了,所以a b 的值还是不变。
那么如何让a b值有变化?见下面代码:
#include <iostream>
using namespace std; // 函数定义
void swap(int &x, int &y)
{
int temp;
temp = x; /* 保存地址 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 x 赋值给 y */ return;
} int main ()
{
// 局部变量声明
int a = ;
int b = ; cout << "交换前,a 的值:" << a << endl;
cout << "交换前,b 的值:" << b << endl; /* 调用函数来交换值 */
swap(a, b); cout << "交换后,a 的值:" << a << endl;
cout << "交换后,b 的值:" << b << endl; return ;
}
对x y加了引用,引用相当于给引用的值起了个别名。
比如上面的代码,给a起了个别名,叫作x;给b起了个别名,叫作y。所以x y在交换数值的过程中,实际上交换的是a b。
2、把引用作为返回值
当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。类似于double& setValues( int i ) 。代码如下:
#include <iostream>
using namespace std;
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )
{
return vals[i]; // 返回第 i 个元素的引用
}
// 要调用上面定义函数的主函数
int main ()
{
cout << "改变前的值" << endl;
for ( int i = ; i < ; i++ )
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
setValues() = 20.23; // 改变第 2 个元素
setValues() = 70.8; // 改变第 4 个元素
cout << "改变后的值" << endl;
for ( int i = ; i < ; i++ )
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
return ;
}
得到结果为:
改变前的值
vals[] = 10.1
vals[] = 12.6
vals[] = 33.1
vals[] = 24.1
vals[] =
改变后的值
vals[] = 10.1
vals[] = 20.23
vals[] = 33.1
vals[] = 70.8
vals[] =
当返回一个引用时,要注意被引用的对象不能超出作用域。所以返回一个对局部变量的引用是不合法的,但是,可以返回一个对静态变量的引用。
int& func() {
int q;
//! return q; // 在编译时发生错误
static int x;
return x; // 安全,x 在函数作用域外依然是有效的
}
C++编程学习(十)引用的更多相关文章
- Linux网络编程学习(十二) ----- 结语
该书提前看完了,重点看了第四章和第六章,第七章以后只是大致浏览了一下,如果以后工作中涉及这一块再仔细研究一下,大概花了二十天的样子,主要了解了进程间的通信方式.socket编程以及五种I/O模式,看的 ...
- Linux网络编程学习(十) ----- Socket(第六章)
前言:由于第五章主要介绍了TCP和UDP协议以及两者的包头的字段以及相应的功能,这里就不介绍了,对着字段看功能就好了,后续开始学习第六章 1.Socket Socket实质上就是提供了通信的端点,每个 ...
- 学习ASP.NET Core Razor 编程系列十九——分页
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十八——并发解决方案
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十六——排序
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Blazor编程系列十——路由(中)
学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...
- 现代3D图形编程学习-基础简介(3)-什么是opengl (译)
本书系列 现代3D图形编程学习 OpenGL是什么 在我们编写openGL程序之前,我们首先需要知道什么是OpenGL. 将OpenGL作为一个API OpenGL 通常被认为是应用程序接口(API) ...
随机推荐
- Vue源码(下篇)
上一篇是mount之前的添加一些方法,包括全局方法gloal-api,XXXMixin,initXXX,然后一切准备就绪,来到了mount阶段,这个阶段主要是 解析template 创建watcher ...
- redis 之 redis主从复制
Redis集群中的数据库复制是通过主从同步来实现的 主节点(Master)把数据分发给从节点(Slave) 主从同步的好处在于高可用,Redis节点有冗余设计 主从复制的原理:1. 从服务器向主服务器 ...
- mysql学习指令
mysql 用户管理和权限设置 参考文章:http://www.cnblogs.com/fslnet/p/3143344.html Mysql命令大全 参考文章: http://www.cnblogs ...
- js——form表单验证
用js实现一个简易的表单验证 效果: 代码: <html> <head> <title>js校验form表单</title> <meta char ...
- thymeleaf 在 html和js 中拼接字符串
一.th:text字符串和事件拼接 <span th:text="'Welcome,'+${user.name}"> <span th:text="| ...
- Vue 中引入echarts
安装依赖 npm install echarts -S 或者使用淘宝的镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org ...
- 【剑指Offer面试编程题】题目1521:二叉树的镜像--九度OJ
题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点 ...
- android图片保存到SQLlite如何实现?
//写入数据库 ImageView pic = (ImageView) findViewById(R.id.picture); ...
- bzoj 4747: [Usaco2016 Dec]Counting Haybales
23333,在扒了一天题解之后发现我竟然还能秒题,虽然这是个pj的sb题... (排个序,然后upper_bound和lower_bound一用就行了(是不是有O(1)的查询方法啊??貌似要离散啊,一 ...
- 手写MQ框架(四)-使用netty改造梳理
一.背景 书接上文手写MQ框架(三)-客户端实现,前面通过web的形式实现了mq的服务端和客户端,现在计划使用netty来改造一下.前段时间学习了一下netty的使用(https://www.w3cs ...