前言
說到引用,對于Android開發(fā)工程師來說,肯定是不陌生的。比如Java中我們聲明一個
Person person,這里就是person就是Person的引用,可以讓person = new Person("張三"),即person這個引用指向了"張三"這個對象。
引用概念
大家都知道,變量名實質(zhì)上是一段連續(xù)存儲空間的別名,是一個標(biāo)號(門牌號),那么可能有人會問了,那能不能有多個別名呢?答案是肯定的,也就是說可以有多個引用,引用即變量的別名。
引用的作用
1.可以從函數(shù)中返回多個值。
2.可以修改實參值本身,不需要像值傳遞那樣,函數(shù)處理的是實參數(shù)本地的副本。
3.傳遞地址可以節(jié)省復(fù)制大量數(shù)據(jù)的內(nèi)存空間和時間。
大家看完引用的作用,可能一臉懵逼,但是這不要緊,當(dāng)看完下面的例子,再回頭來看,必然會有不一樣的體會。
引用的初次相識
#include<iostream>
using namespace std;
void main() {
//變量名就相當(dāng)于門牌號(也就是內(nèi)存空間的別名,那可不可以有多個名字?)
int a = 10;
//b就是這個內(nèi)存空間的另外一個別名
//C++中的一個引用(C中是沒有引用的)
int &b = a;
cout << b << endl;
getchar();
}
這里變量b就是a的引用,用&加以標(biāo)識。在C中是沒有引用的概念的,引用是在C++中增加的。
引用的應(yīng)用:
1.值交換
我們先來看看值交換的指針寫法:
#include<iostream>
//指針值交換
void swap_1(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
再讓我們來看看值交換的引用寫法:
//引用值交換
void swap_2(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
主函數(shù)main調(diào)用值交換函數(shù):
void main() {
int x = 10;
int y = 20;
printf("%d, %d\n", x, y);
//swap_1(&x, &y);
//a成了x的別名,b成了y的別名
swap_2(x, y);
printf("%d, %d\n", x, y);
getchar();
}
打印的結(jié)果:
10, 20
20, 10
這里驗證了引用作用的第二條,引用改變的是參數(shù)本身,而不是參數(shù)的副本。因為這里我們打印的是變換之前x和y的值、變換之后x和y的值,如果不是改變參數(shù)本身,這里打印的應(yīng)該都是10和20。
注意:
由于引用參數(shù)傳遞的是實參的地址,因此在調(diào)用函數(shù)時,不能向引用參數(shù)傳遞常數(shù)。比如此例中的swap_2(x, y),如果寫成swap_2(10, 20)就是錯誤的。
2.代替二級指針
先來看看二級指針的例子:
先定義一個結(jié)構(gòu)體:
#include<iostream>
struct Teacher {
char* name;
int age;
};
二級指針的寫法
void getTeacher(Teacher **p) {
Teacher *temp = (Teacher*)malloc(sizeof(Teacher));
temp->age = 20;
*p = temp;
}
然后我們再來看看引用是怎樣代替二級指針的:
void getTeacher(Teacher* &p) {
p = (Teacher*)malloc(sizeof(Teacher));
p->age = 40;
}
void main() {
Teacher *t = NULL;
//getTeacher(&t);
getTeacher(t);
printf("%d\n", t->age);
getchar();
}
打印的結(jié)果分別是20、40。
是不是簡單了好多呢?
指針常量與常量指針
指針常量
#include<iostream>
void main() {
//指針常量,指針的常量:不能改變地址,但是可以修改它指向的內(nèi)容
int a = 2, b = 3;
int *const p1 = &a;
//p1 = &b; //這樣是不行的
*p1 = 4;
printf("%d\n", *p1);
}
指針常量,不能改變地址,但是可以修改它指向的內(nèi)容
常量指針
#include<iostream>
void main() {
//常量指針,指向常量的指針:能改變地址,但是不可以修改它指向的內(nèi)容
const int *p2 = &a;
p2 = &b;
//*p2 = 4; //這樣是不行的
getchar();
}
常量指針,能改變地址,但是不可以修改它指向的內(nèi)容
3.常引用
#include<iostream>
using namespace std;
void myPrintf(const int &d) {
cout << d << endl;
}
void main() {
//const int a;
//引用必須要有值,不能為空
//int &a = NULL;
//常引用
int a = 3, b = 4;
const int &c = a;
//c = b; //常引用不能再重新被賦值
//字面量
const int &d = 70;
myPrintf(c);
getchar();
}
注意:
1.常引用類似于Java中的final
2.引用必須要有值,不能為空
3.常引用不能再重新賦值
4.常引用作為函數(shù)的參數(shù)
5.常引用作為字面量來使用
指針是變量的地址,引用是變量的別名
#include<iostream>
using namespace std;
struct Teacher {
char name[20];
int age;
};
void main() {
Teacher t;
Teacher &t1 = t;
Teacher *t2 = &t;
cout << sizeof(t1) << endl; //24
cout << sizeof(t2) << endl; //4
getchar();
}
打印結(jié)果為:
24
4
由打印結(jié)果我們知道t1是24字節(jié),t2是4字節(jié),而該結(jié)構(gòu)體是20(name) + 4(age) = 24字節(jié),指針是4字節(jié),我們就可以得出:
指針是變量的地址,引用是變量的別名
展望
本篇博客主要介紹了C++中的引用,接下來我將介紹C++中的類與函數(shù),由于篇幅較長,故分為上、中、下三篇,敬請期待!