C++ 复合类型之引用和指针
复合类型是指基于其他类型定义的类型。C++有很多复合类型,介绍其中的引用和指针
对变量的声明的解释:一条简单的声明语句是由一个数据类型和紧随其后的变量名列表组成。其实更通用的描述是:一条声明语句由一个基本数据类型和紧随其后的一个声明符列表组成。每个声明符命名了一个变量并指定该变量是与基本数据类型有关的某种类型。
2.3.1 引用
引用即别名,引用是为已存在的对象所起的另外一个名字。在初始化变量时,初始值会被拷贝到新建的对象中。而在定义引用时,程序会把引用和它的初始值绑定在一起,而不是拷贝。一旦初始化完成,引用将和初始化对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。
- 引用即别名,对引用的操作实际是对引用所绑定对象的间接操作
- 给引用赋值必须是已存在的对象(变量),
- 引用必须初始化。
int val = 1024;
int &temp = val;
int &temp2 = temp;
cout<<--temp<<" "; //1023
cout<<val<<" "; //1023
cout<< --temp2<<" "; //1022
cout<<temp<<" "<<val<<" "; //1022 1022
int &refval = 10; //错误 引用类型的初始值必须是一个对象
double dval = 3.12;
int &ref = dval; //错误 此处引用的初始值必须是int型对象
int i,&r1 = i;
i = 5;
r1 =10;
cout<<i<<" "<<r1<<endl; //10 10
2.3.2 指针
指针是指向另外一种类型的复合类型,与引用类似,指针也实现对其他对象的间接访问。而指针与引用有很多不同点,其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内可以先后指向多个不同对象。而引用初始化一旦完成,引用将和初始化对象一直绑定在一起。其二,指针不必须初始化,若没有初始化指针,将指向随机地址,即不确定的值。
int *P1,*P2;
double dp1,*dp2; //dp1是double类型变量,dp2是指向double类型的指针变量
double dval;
double *p = dval; //正确 指针p是指向double类型的指针
double *p2 = p; //正确 指针p2也是指向double类型的指针
int *pi = dval; //错误 试图把double类型赋值给int型指针
int *pi = p; //同上
指针的值(即地址)应属于下列4种状态之一
1、指向一个对象
2、指向紧邻对象所占空间的下一个地址
3、空指针,没有指向任何对象
4、无效指针,即除上述三种的其他类型
试图以拷贝或其他方式访问无效指针的值都将报错,这一点和使用未经初始化的变量是一样的(变量会默认初始化随机值),编译器并不负责检查此类错误。因此访问无效指针的后果无法预计。
尽管2 3种指针是有效的,但其使用也收到限制。显然这些指针没有指向任何具体对象,所以试图访问此类指针对象的后果也不确定,无法预计。
int* p1,p2; //p1是指向int的指针,p2是int类型的数据,这样写容易产生误导
//规范写法:
int *p1,*p2;
通过*个数可以区分指针的级别,**表示指向指针的指针, * * *表示指向指针的指针的指针,以此类推。
int ival = 44.45;
int *pi = &ival; //一级指针
int *pd = &val; //pd和pi指向同一个对象val
int **ppi = π //ppi指向pi指针 所指对象
如图描述了他们的关系:
指针可以嵌套使用,解地址运算符*同样也需要嵌套使用。如, *pi的值是int型数ival的值,而 *ppi的值是指针 *pi,**ppi才是最初指向的int型数ival。
引用只是一个其绑定变量的别名,引用不是对象,因此不存在指向引用的指针。但指针是变量,可以定义对指针的引用
int i = 40;
int val = 100;
int *p = &i;
cout << p << endl; //输出i的地址
int *&r = p; //定义指针的引用,r指向 指针变量p
r = &val; //r引用了指针p,因此现在p指向变量val
cout << *r << endl; //100
cout << p << endl; //输出val的地址
cout << *p<<endl; //100
*r = 0; //解地址r = 0; val的值,*p和*r的值都为0
Test:
下面定义合法吗?原因?
int i=424; void *p =&i; long *lp = &i;
说明变量的类型和值:
int *ip,i, &r = i;
int i,*ip = 0;
int * ip,ip2;
- 其他指针操作
int val = 1024;
int *p1 = 0; //合法 空指针
int *p2 = &val; //合法 p2指向val
if(p1) //p1空指针 值0 false
...
if(p2) //p2存放val的地址 true
...