1、引用
引用不是独立的数据类型,实际上是对变量起了别名.
int& b = a; //相当于给a起了个别名.
(1)变量 指针 引用
2.1.引用必须初始化,指针可以不初始化
int a = 66;int& b = a;
int&c; //error.
2.2.引用不能为空,指针可以为空
int a= 66;
int& b = NULL; //error.
const int& b = NULL; //ok
const int& b = 0; //ok.
int* p =NULL; //空指针
2.3.引用不能更改换目标,指针是可以的
int a = 66;
int& b = a;
int m = 118;
b = m; //赋值,是把m的值赋给a.
2.4.不能声明引用型的数组,可以声明指针数组
int a[10];
int* pa[10];
int& a[10] ; //error. 因为引用本身不占内存,数组要求一段连续的内存空间,所以报错
2.5.指针和引用符号停靠问题
2.5.1指针符号停靠问题.
int* p; int * p; int *p;int* p ,q; //q是整型变量;
int *p,*q; //q指针;
不成文的规定:当定义一个指针时,我们习惯让*靠在数据类型,当我们定义多个指针时,我们习惯让*靠在变量名称边.2.5.2引用符号停靠问题.
int a = 66;int& b = a;
int & b = a;
int &b = a; //三种方法一样.
int c = 118;
int &b = a,&d = c;
引用符号不成文的规则同上.
不成文的规定:当定义一个引用时,我们习惯让&靠在数据类型,当我们定义多个引用时,我们习惯让&靠在变量名称边.
2.6.起别名来定义
typedef int* PINT;
PINT i,j; //这两个都是指针
typedef int& RINT;
RINT r = a,s = b; //两个都是引用#define PINT int*
PINT i,j; //i是指针,j是整型.
3、注意:
引用的本质还是指针,但是建议使用引用而不是指针
double d = 3.14;
double& m = d;
==> double* const pm = &d; 指向不能改,但指向的值是可以改的。==> const double* pm = &d; 指向可以改变,但指向的值不可以改变。
2.7.引用作为函数的参数
小结:(1)可以定义指向指针的指针,但是不可以定义指向引用的指针
如:int a = 66;
int* pa = &a;int** ppa = &pa; //ok
int& b = a;
int& *pb = &b; //error 编译器不识别 没有规定这种语法.
(2)可以定义引用指针的引用,不可用定义引用 引用的 引用.
(即是可以定义指针的引用,不是不能给引用定义引用).int a = 66;
int* pa = &a;
int*& pb = pa; //ok
int& b = a;
int&& c = b; //error.
(3)可以定义指针数组,但是不能定义引用数组. 不过可以定义数组的引用.
int num[5]int* p[5];
int& p[5]; //error
int (&q)[5] = num //ok;
int (*q)[5] = &num //ok;
注意: 在程序中函数的形参尽可能的加引用,尽可能的加const.
//使用引用型参数可以在函数中对实参变量做修改
//使用引用型参数可以避免参数传递过程中的数据拷贝
//尽量使用常引用,可以避免实参的值在函数中被意外改变
//8.引用作为函数的返回值:
//注意
//永远都不要返回一个局部变量(函数的形参)的引用,可以返回全局变量,静态的局部变量,成员变量
//实参的引用,动态内存。
//引用作为函数的返回值
struct S
{
int n;
int& fn(void)
{
return n;
}
};
int& fnReturn(void)
{
int n = 66; //返回了局部变量的引用
return n;
}
void daoluan(void) //捣乱
{
int i = 100,j = 200;
}
int& fnReturnEx(void)
{
static int num = 66;
return num;
}
int& fnReturnExEx(int& n)
{
return n;
}
//引用作为函数的参数
void fn6(char* & pstr)
{
pstr = "good!";
}
void fn5(char** pstr)
{
*pstr = "world!";
}
void fn4(char* pstr)
{
pstr = "world!";
}
//引用传递
void fn3(int& n)
{
n = 250;
}
//址传递
void fn2(int *p)
{
*p = 118;
}
//值传递
int fn( int n)
{
return n = 118;
}
void swapP(int* a,int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swapR(int& a,int& b)
{
int temp = a;
a = b;
b = temp;
}
void FunReferenceEx()
{
int num = 888;
cout<<"num = "<<num<<endl;
cout<<"------------------------------"<<endl;
fn(num); //值传递
cout<<"num = "<<num<<endl;
cout<<"------------------------------"<<endl;
fn2(&num); //址传递
cout<<"num = "<<num<<endl;
cout<<"-------------------------------"<<endl;
fn3(num); //引用
cout<<"num = "<<num<<endl;
cout<<"--------------------------------"<<endl;
char* pStr = "hello!";
fn4(pStr); //
cout<<"pStr = "<<pStr<<endl;
cout<<"--------------------------------"<<endl;
fn5(&pStr); //二级指针
cout<<"pStr = "<<pStr<<endl;
cout<<"--------------------------------"<<endl;
fn6(pStr); //一级指针的引用.
cout<<"pStr = "<<pStr<<endl;
// cout<<"--------------------------------"<<endl;
// fn7(&pStr); //二级指针的引用.
// cout<<"pStr = "<<pStr<<endl;
}