复合类型——指针和引用
2015-10-17 21:53
260 查看
概述
复合类型,顾名思义就是指基于其他类型定义的类型,主要有指针与引用。本文将先分别介绍这两种类型,接着将介绍二者之间的异同之处。一般来讲,一条声明通用的格式为:
基本数据类型 声明符。在简单声明语句中,声明符就是变量名,换句话说,此时的变量类型就是声明符前面的基本数据类型。而复合类型就是一种基于基本数据类型的更为复杂的数据类型。
指针
指针定义
指针是一中“指向”另外一种类型的复合类型。简而言之,指针是一种实现对对象间接访问的类型。指针本身也是对象,该对象存放了指针所指对象的地址,以此来实现对对象的间接访问。定义指针类型的方法就是将声明符写成
*p格式,其中p是变量名,在一条声明语句中可以声明多个指针类型的变量,每个变量名前必须有*。具体格式如下:
int *p, *q; //声明了两个指针类型的变量p和q,p,q都指向int类型的对象 double *p, i; //声明了一个指令类型的变量p,该变量p指向一个double类型的对象和一个double类型变量i
获取对象地址
既然指针对象存储的是指针所指对象的地址,那么如何获取对象的地址呢?通常在变量名前加&符号来获取对象的地址。int i = 41; //定义并初始化一个int类型的变量i int *p = &i; //定义一个指向int类型对象的指针p,p存放的是i的地址,也就是说p是指向i的指针。
注意:这里的符号& 是取地址符,和之后将要在引用章节中提到的&有着不同含义在那里是引用声明符。
一般来说,指针的类型必须和它所指向的对象严格匹配。因为在一条声明语句中指针的类型实际上是用来指定它所指向对象的类型,所以二者必须严格一致。
double d; //声明一个double 类型的对象d int *p = &d; //错误:不可以用int类型的指针指向一个double类型的对象 double *q = &d; //正确:可以用double类型的指针指向一个double类型的对象
指针的值
通常,指针的值无外乎以下4中:- 指向一个对象
- 指向相邻对象所占空间的下一个位置
- 空指针,如int *p = nullptr;
- 无效指针,除以上各种情况
赋值与访问
赋值和访问可以分为对指针本身的赋值和访问以及对指针所指对象的赋值和访问。char *p1 = "abc", *p2= p1;//指针p1和p2都指向字符串"abc"的首地址 int a = 2, b = 3; int *p3 = &a;//对指针本身的赋值,将int类型变量a的地址赋值给p3 p2 = p1 + 1;//对指针本身的运输和赋值,此时p2将指向字符串"abc"的'b'的地址 cout << *p3 << endl;//访问p3所指向的对象
引用
引用是为对象取的一个别名,引用类型引用另外一种类型通过将声明符写成&f形式来定义引用类型。int ival = 2; int &reval = ival;//引用必须初始化
学习引用必须时刻注意它的定义:引用是为对象起的另外一个别名,简而言之,提到引用第一反应就是别名。这样,很多问题就迎刃而解,比如:引用必须初始化,引用是别名,不初始化怎么知道它是哪个对象的别名,再比如,引用一经初始化就不能再指向其他对象了,否则,作为别名却指向多个对象,这样就相当于一个一个引用是多个对象的别名。
既然引用就是其所引用对象的别名,所以,对引用的操作就是对所引用对象的操作。
const限定符与指针和引用
首先简单的介绍一下const这个声明限定符,被const修饰的变量和普通变量大体没有出别,本const修饰对象主要限制在于对该变量的操作指限于不改变其内容的操作。还有一个必须了解的是,const只影响被它修饰的对象,时刻记住这一点是十分有必须要的。指向常量对象的指针
指向常量的对象的指针,顾名思义,就是指针所指向的对象是常量,但是也不完全对,因为这样乍看好像并没有什么问题,但是如果细想,被指对象是常量,当然是不想被修改,现在有指针指向它,是不是可以通过指针修改它呢?举例说明:const double pi = 3.14; double r = 1; double *p = & pi; /*错误:变量pi是一个double类型常量,如果本语句正确,那么程序员将可以通过指针p来改变pi的值了*/ const double *p1 = π /*正确:指向常量对象的指针,无论通过指针p1还是变量pi本身都不能改变pi的值*/ const double *p2 = &r;//正确:将一个指向常量的指针指向一个普通变量
从上面的代码中,我们可以看出,可以将一个指向常量的指针指向一个常量或者普通变量,二者的主要出别在意前者不论通过指针还是变量本身都不能改变变量的值,而后者则不同——不可以通过指针来改变变量的值,但是可以通过变量本身来改变。总之,出别这一点的关键在要始终记住,const影响的只是它所修饰的那个变量,和其他的没有关系。
常量指针
现在,我们应该会想到,指针需要从两个方向来思考——指针本身和指针所指向的对象。指针本身也是对象当然也可以被const修饰。这就是这一小结中的常量指针。正如该名称所示,常量修饰的是指针,就是说常量指针一经初始化后就不能再指向其他对象。那么问题又来了,是否可以通过常量指针修改其指向对象的值呢?答案是肯定的,正如上文所讲,const 只影响被其修饰的对象,和其他对象无关。double pi = 3.14; double *const p = π //常量指针
从上面的实例代码中我们可以知道,常量指针所指对象也不必是常量。
常量引用
和指针类似,引用也可以指向一个常量对象,也可以通过const限制引用不可修改所指对象。与指针不同之处在于两者都是常量引用,即对const的引用。这里,我们要记住,引用不是对象,只是被引用对象的别名而已。引用一经绑定便不可以改变其绑定的对象,那么就不存在类似与常量指针的概念了,换而言之,在引用关系这个层面上是不受const的影响的。const所能够影响的只有对对象的操作上,因此,在讲const和引用时,我们只需关注引用和被引用对象操作上,不必关心引用关系。可能有读者就会有疑问了,如果一个对象可以通其本身来改变,但是不能通过引用来改变该如何操作?int a = 12; const b = 13; const int &c = b;//将常量引用绑定到一个常量上 const int &d = a; //将一个常量绑定到一个普通对象上
此次,容易使人迷惑的是,一个对const 的引用却可以绑定到一个普通变量上。其实,也不难理解,因为我们有上面的需求——可以通过变量本身改变变量额度值,但是不可以通过引用来改变。要更好的理解这个问题,我们需要知道它是如何实现的,
const int &d = a其实等价于:
const int temp = a; const int &d = temp;
简单来讲,就是变压器对代码做了转换,d实际上绑定到了一个临时变量 temp上。
总结
区别指针和指针所指向的对象指针是对象,其中存放的是其所指对象的地址
指针所指对象是,指针对象所存地址对应空间存放的内容
const限定符只影响它所修饰的变量。
引用是变量的一个别名,记住这一点将解决大部分关于引用的疑惑
变量和它的引用之间是绑定关系,而非赋值关系,即,对引用值的修改将改变变量的值
定义引用时必须对其进行初始化,且初始化必须是一个变量,否则,将不知道引用到底是谁的别名
初始化一旦完成,变不可更改,也就是说该引用不可再绑定到其他变量上了,否则,一个别名将是若干个变量的别名,这样将导致不知道别名到底绑定了哪变量了。
因为引用只是一个别名而已,所以引用不是对象,没有实际的地址,进而得出,不能定义指向引用的指针
相关文章推荐
- static_隐式参数_继承_重写_toString_组合JAVA036-042
- MySQL数据优化
- 明年的 ---学习计划
- javascript倒计时代码
- 011.商品打折
- VBScript的中ByRef和ByVal的不同
- spring beans源码解读
- 移动硬盘挂载后访问权限修改
- Android第三方开源框架之SlidingMenu详解
- 渲染到纹理(Render To Texture, RTT)详解
- 今天开博
- JavaScript采用append添加的元素错误
- (转载)R14也称作子程序连接寄存器
- 如何在DOS下修改管理员密码
- 表格边框问题
- 华为S9306破解console密码及清空配置
- query 获取本身的HTML
- python 文件输入和输出
- gns3 1.3.9升级到gns3 1.3.11后,升级gns3 iouvm解决版本不匹配问题
- 彩虹七种颜色的RGB值十六进制