您的位置:首页 > 编程语言 > C语言/C++

(C++)指针和引用

2018-03-15 02:14 127 查看
一、引用的概念

引用:不是定义一个新的变量,而是给一个已经定义的变量重新起一个别名。

#include <iostream>
using namespace std;

int mian() {
int a = 10;
int* p = &a;
//内存开辟一段空间,名为a,a内内容为10,定义指针p指向a,即指针p内保存a的地址

//引用
//格式:类型& 引用的变量名 = 已定义过的变量名
int& b = a;//b引用了a,b是a的别名
int& c = a;
int& c = b;
//给刚才开辟的a重新命名为b,c

cout<<a<<endl;//10
cout<<b<<endl;//10
cout<<c<<endl;//10

c = 20;
cout<<a<<endl;//20
cout<<b<<endl;//20
cout<<c<<endl;//20
return 0;
}

//引用:
//1.引用必须初始化;
int i; // √
int& j; // ×
//2.一个变量可以取多个别名;
//3.引用只可以在初始化时引用一次,不能再变成其他变量的别名

int main() {
int a = 10;
int& b = a;
int i = 100;
b = i;
//储存10的内存,同时命名为a,b;b = i即把i内值赋值给b;
//引用在初始化时只能引用一次,之后在=其他变量,看作是赋值
cout<<b<<endl;//100,且此时a,b均为100
return 0;
}


二、const 引用->引用常量

#include <iostream>
using namespace std;

int main() {
int a = 4;
const int& b = a;
a = 5;// √ a改变,b也会改变
b = 5;// × 不能给常量赋值
return 0;
}

int main() {
const int a = 10;
int& b = a;// ×
const int& b = a;// √ 常量具有常性,只有常引用可以引用常量

int& c = 20;// × 20是常量,引用是为某个变量起个别名,而且,20的值不可以改变,c的值可以改变,所以不可以这样引用
const int&c = 20;// √ c是20这块区域的别名

int d = 10;
double e = d;//隐式类型的转换(!可能会丢失数据)

//隐式类型的转换
(http://img.blog.csdn.net/20180315020214467?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2lyYWZmZV8yNTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

double& f = d;// × 实际上是将f命名给了临时变量,因为临时变量不可以更改,所以必须要加const才可以编译通过
const double& f = d;// √
return 0;
}


三、引用的应用

1.用引用做参数(swap2)

#include <iostream>
using namespace std;

void swap1 (int* l,int* r) {//传进来&a(地址)
int tmp = *l;//解应用之后为值
*l = *r;
*r = tmp;
}

void swap2 (int& l,int& r) {
int tmp = l;
l = r;
r = tmp;
}

void swap3 (int l,int r) {
int tmp = l
l = r;
r = tmp;
}
int main() {
int a = 10;
int b = 20;
swap1(&a,&b);//传地址
//指针,将a,b的地址传给指针l,r,之后将a,b之内数值交换;

swap2(a,b);//传引用
//将a,b引用传入函数,即:int& l = a;将内存a重新命名为l,将l内值改变,即改变同一块内存,a的值,b同理;

swap3(a,b);//传值
//这样等同于一般函数,只传值,所以不改变a,b本身的值,交换就没有完成,而且耗费内存和时间,效率很低
return 0;
}


2.引用做返回值

#include <iostream>
using namespace std;

typedef struct Big {
int a[10000];
}Big;

//传值
void func1(Big big) {
//......
}

//传指针
void func2(Big* big) {
//......
}

//传引用
void func3(Big& big) {
//......
}

//传const引用
void func4(const Big& big) {
//......
}

int  main() {
Big b1;
func1(b1);//浪费空间,效率低
func2(b2);//另外开辟一个指针的空间
func3(b3);//不需要另外开辟空间,只是给原本的变量起了一个别名
func4(b4);//***最好使用这个,非但不用额外开辟空间,减少空间消耗;而且里面值改变,外面的值不受影响

}

int Add(int a,int b) {
int c = a + b;
return c;
}

int& Add(int a,int b) {
int c = a + b;
return c;
}

int main() {
int ret = Add(1,2);//匿名临时变量,编译器在main里开辟空间,传值返回
int& ret = Add(1,2);//栈帧内部有一处空间被命名,类型为int&,这段空间内储存c的值;空间存在不确定性,当下一次被占用时很可能改变,或者直接改为随机值
const int& ret = Add(1,2); //必须加const,这样这段int&类型空间中的值就不能被改变,值可以被一直保存下来,不会随函数的结束而被释放或者占用
}

(http://img.blog.csdn.net/20180326153455768?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2lyYWZmZV8yNTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)


3.汇编层看引用的特性

① 不要返回一个临时变量的引用,出了作用域就已经不存在了

② 出了作用域,返回的变量还存在,尽量使用引用,减少临时变量的产生(高效,不浪费空间)

4.引用和指针的区别

语法:未开辟空间

汇编层:开辟空间

指针++:+类型大小

引用++:+1(加到变量上去)

空指针解应用会奔溃
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++