指针*和引用&的区别使用
引用&
首先,&不是地址运算符,而是类型标识符的一种,就像*也不是指针运算符一样。 本篇偏向于&运算符。
&:可以叫它引用运算符
*:可以叫它解除指针运算符
就像char *意为指向char的指针一样,int&意为指向int 的引用。
栗子来一颗:
int a;
int &at = a;
//上述声明允许将at和a互换,它们指向相同的值和内存单元,就像连体婴一样。
上面这个栗子其实很有内涵在里面 我为什么不写成下面这个形式呢?
int a;
int &at;
at = a;
在指针中是可以的,但是&不允许,&必须在声明时将其初始化。
引用经常被用作函数参数,使得函数中的变量名成为调用程序中变量的别名。这种调用方法我一直搞得晕晕的,正好这次一次性根除。这种传递参数的方法称为按引用传递。按引用传递允许被调用函数能够访问调用函数中的变量。这是C++相比C的一个超越。 来个经典的栗子:
void swap_a(int &a,int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
//顺便来个指针的
void swap_b(int *a,int *b)
{
int temp;
temp = *a; //a,b是指针,*a,*b才是int
*a = *b;
*b = temp;
}
int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 4;
swap_a(a,b); //看仔细咯,这个是引用调用
swap_b(&a,&b); //看仔细咯,这个是指针调用
//如果理解不了,这样理解:参数中的*和&只是走个过场,告诉人家那个参数是什么类型的
//调用函数时的参数是a,不是*a,也不是&a
//所以&a传的这个a是一个int类型,而*a的这个a就是指针,地址,所以要取地址传给它
//虽然我语文不好,但是都讲到这份上了那应该是可以理解了
return 0;
}
如果你的意图是让函数使用传给它的信息,又不想把这些信息进行改动,那么应该使用const。 将引用参数声明为const数据的好处有这些:
防止无意中被修改。
使用const参数可以兼容非const传参。
将引用用于结构
C++引入引用主要就是为了和结构和类。 它还通过让函数返回指向结构的引用而增添了一个有趣的特点,这与返回结构有所不同。
//代码太长,放段伪代码吧
struct Str
{
};
Str& test(Str &a,const Str &b)
{
//从b中取值,对a进行填充
return a;//其实可以做void类型,没必要多此一举
}
int main()
{
Str a,b,c;
//b是有初值的,这是伪代码
c = test(a,b);
return 0;
}
如果test函数返回一个结构,而不是指向结构的引用,将把整个结构体复制到一个临时位置,再将这个拷贝复制给c,但是现在返回值为引用,将直接将a复制到c,效率更高。
返回引用时最重要的一点是:应避免返回函数终止时将不再存在的内存单元的引用。 下面是一个反面教材:
Str& test(const Str &d)
{
Str &e;
···
return e;
}
何时使用引用参数?
程序员能够修改调用函数中的数据对象。
通过传递引用而不是整个数据对象,可以提高程序的运行速度。
指针
1、指针和const
将const用于指针有一些很微妙的地方。 可以用两种不同的方式将const关键字用于指针。
int age = 20; const int * pt = &age;
该声明指出,pt指向一个const int,因此不能使用pt来修改这个值。
现在来看一个很微妙的问题:其实age并不是一个常量,只是对于pt来说,它是一个常量。
就是说age可以改,只不过不能用pt来改而已。
注意点:不允许将常量数据赋值给非常量指针,个中理由就不用多解释了吧。
const int age = 20; int * pt = &age;
int sloth = 80; int * const finger = &sloth;
这种声明格式使得这个指针只能指向sloth,不过可以通过这个指针修改sloth的值。
2、通过指针返回字符串的函数
现在,假设需要一个返回字符串的函数,是的,函数无法返回一个字符串,但是可以返回字符串的地址,这样效率更高。
void test(char *rc)
{
···
memset(rc,字符串);
···
}
相当于是使用回调函数,我个人比较喜欢这一套模式。 3、通过指针返回结构
具体操作参考第二点。 当然,这里还有另外的应用场景:
void test2(const JieGouTi1 *a,JieGouTi2 *b)
{
//将a中的某些值赋值给b
}
//这里有一个注意点,传进去赋值的结构体指针最好用const.
4、函数指针
关于为什么要使用函数指针,我的理解还不是很深刻,毕竟功力不足。但是我知道那些回调函数都是用函数指针的,所以对函数指针必须要理解好。 这叫啥,“但行好事,莫问为啥”。
函数指针完成任务的流程是这样的:
//获取函数的地址 //声明一个函数指针 //使用函数指针来调用函数 获取函数地址
获取函数地址那是比较简单的事,如果说 void Hanshu();这是一个函数,那么它的地址就是 Hanshu。 如果函数Hanshubaba();要调用这个函数,是这样的:Hanshubaba(Hanshu); 切记不能写成:Hanshubaba(Hanshu());
声明函数指针
假设现在有这么一个函数:int test3(void *arg); //这个arg参数,回调函数里面用,要解释有点长。 现在要将之改成函数指针形式:int (*test3)(void *arg);
首先,将test3更换成(*test3),因此,(*test3)也是函数,那么test3就是函数指针。 为声明优先级,需要将 *test3 括号起来。
- HDU 2034 人见人爱A-B
- Hadoop数据分析平台实战——030Hadoop Shell命令02(熟悉linux跳过)离线数据分析平台实战——030Hadoop Shell命令02
- Hadoop数据分析平台实战——070深入理解MapReduce 02(案例)离线数据分析平台实战——070深入理解MapReduce 02
- Hadoop数据分析平台实战——040HDFS介绍(熟悉基础概念跳过)离线数据分析平台实战——040HDFS&JAVA API(熟悉基础概念跳过)
- Hadoop数据分析平台实战——060深入理解MapReduce 01(案例)离线数据分析平台实战——060深入理解MapReduce 01(案例)
- 利用向量积(叉积)计算三角形的面积和多边形的面积
- HDU 1556 Color the ball
- Hadoop数据分析平台实战——080HBase介绍和安装离线数据分析平台实战——080HBase介绍和安装
- Hadoop数据分析平台实战——130Hive Shell命令介绍 02(熟悉Hive略过)离线数据分析平台实战——130Hive Shell命令介绍 02(熟悉Hive略过)
- ECJTUACM16 Winter vacation training #4 题解&源码
- Hadoop数据分析平台实战——090HBase shell客户端和Java Api介绍离线数据分析平台实战——090HBase shell客户端和Java Api介绍
- Hadoop数据分析平台实战——140Hive函数以及自定义函数讲解离线数据分析平台实战——140Hive函数以及自定义函数讲解
- 深入理解树状数组
- Codeforces 712C Memory and De-Evolution
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Scoped 样式穿透
- 你不知道的this(1)
- PyTorch模型转TVM模型全流程记录
- 一次 Node.js http 连接无法复用的问题排查
- 基于UE4/Unity绘制地图基础元素-线(上篇)
- 编码、R 与 Windows (一)
- 【5分钟玩转Lighthouse】Python绘制图表
- Matt Dowle 演讲节选(二)
- 帝国CMS的sitemap.xml设置和生成
- 【推荐】搭建你的免费 R 云端服务器
- ShareX 对接tu.my图床实现截图和图片自动上传
- 【技巧】如何快速按照日期分组
- 为什么 ggplot2 不支持两个 y 轴?
- 宝塔面板或者LNMP下安装php的mongodb扩展
- 风格迁移