引用和指针
- 引用的概念及用法
引用:就是给一个变量起个别名。
语法 : 定义的格式为: 类型 &引用变量名 = 已定义过的变量名;
int a=10;
int &b=a;
这里b就是a的别名
引用的特点:
1. 一个变量可取多个别名
2. 引用必须初始化
3. 引用只能在初始化的时候引用一次,不能改变为再引用其他的变量。
注意:
若被指定的值是个常变量,则引用过程中为保证值不被改变必须加const,如:
const int a=10;
const int &b=a;
const int &c=100;//成立
简单记住一个原则,范围可以由大变小,但不能由小被放大
扩展:
int i=0; double d=1.111; i=d;//隐式类型转换—-相近类型//会丢失数据
int* p=(int*)i;//成立
const &j=d;//成立
原因:
- 引用做参数
1、完成值的交换(改变函数内部的值)和指针效果一样
void swap(int &x, int &y)
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int a = 0, b = 1;
swap(a, b);
printf(“%d %d “, a, b);
system(“pause”);
return 0;}
2、直接传值的话又要开辟空间,若值过大,浪费空间,使用指针和引用都可以解决这个问题。
typedef struct Big
{
int a[10000];
}Big;
void Read(const Big& b )
{
b.a;
}
int main()
{
Big big;
Read(big);
system("pause");
return 0;
}
引用做返回值
引用做返回值(出了当前作用域这个对象还在)(静态的或全局的)在函数运行的过程中,在主函数中会开辟一块返回值所存在的空间,在这个函数内部空间通过return语句将值直接传到这块地址中,这个过程中有个临时变量eax,所以接受时也必须加const。(语法上没有开辟空间,只是起了个别名,实际上底层实现和指针一样开辟了空间)
int Add(int a, int b)
{
int c = a + b;
return c;
}
int main()
{/*
Big big;
Read(big);*/
const int& ret = Add(1, 2);
printf(“%d\n”,ret);
system(“pause”);
return 0;
}
汇编层看引用的特性
引用和指针的区别
1、引用不可以为空,但指针可以为空。 使用指针之前必须做判空操作,而引用就不必。
2、引用的大小是所指向的变量的大小,因为引用只是一个别名而已;指针是指针本身的大小,4个字节。
3、引用比指针使用起来形式上更漂亮,使用引用指向的内容时可以之间用引用变量名,而不像指针一样要使用*;定义引用的时候也不用像指针一样使用&取址。
4、引用比指针更安全。由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用很安全。对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全。const
指针虽然不能改变指向,但仍然存在空指针,并且有可能产生野指针(即多个指针指向一块内存,free掉一个指针之后,别的指针就成了野指针)。
总而言之,言而总之——它们的这些差别都可以归结为”指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名,引用不改变指向。”
>
★相同点:●都是地址的概念;
指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。
★不同点:
●指针是一个实体,而引用仅是个别名;
●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;
●引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有
的, 前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变)●引用不能为空,指针可以为空;
●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;
●指针和引用的自增(++)运算意义不一样;
●引用是类型安全的,而指针不是 (引用比指针多了类型检查