说道C++的指针,不少人都很头疼,也很confuse。常常把它和变量名,引用(reference)等混淆,其实这最主要的缘由是不少程序员对于基本知识的掌握有问题,从而致使的不少基本概念的混淆。本文就是从最基本的概念讲起,着重分析和比较指针和引用。主要从如下几个方面着重的讲解:c++
1. 变量(variable)的表现形式;程序员
2. 指针的结构和原理;数组
3. 引用的结构和原理;函数
4. 指针在Array中的应用和注意事项;spa
5. 指针不能dereference的几种状况;翻译
一:变量的形式指针
说道变量,不少人都以为很是简单,天天都在定义变量,应用变量。但是有没有停下脚步细细的品味一下具体什么是变量呢?变量(variable)的定义在计算机科学中究竟是如何定义的?而后variable究竟是在内存中如何存储值的呢?那么跟着上面的问题,咱们来一一的解答,首先最重要的,variable的定义,当你申明一个变量的时候,计算机会将指定的一块内存空间和变量名进行绑定;这个定义很简单,但其实很抽象,例如:int x = 5; 这是一句最简单的变量赋值语句了, 咱们常说“x等于5”,其实这种说法是错误的,x仅仅是变量的一个名字而已,它自己不等于任何值的。这条statement的正确翻译应该是:“将5赋值于名字叫作x的内存空间”,其本质是将值5赋值到一块内存空间,而这个内存空间名叫作x。切记:x只是简单的一个别名而已,x不等于任何值。其图示以下:code
变量在内存中的操做实际上是须要通过2个步骤的:blog
1)找出与变量名相对应的内存地址。内存
2)根据找到的地址,取出该地址对应的内存空间里面的值进行操做。
二:指针的结构和原理
首先介绍到底什么是指针?指针变量和任何变量同样,也有变量名,和这个变量名对应的内存空间,只是指针的特殊之处在于:指针变量相对应的内存空间存储的值刚好是某个内存地址。这也是指针变量区别去其余变量的特征之一。例如某个指针的定义以下:
int x = 5; int *ptr = &x;
ptr便是一个指正变量名。经过指针获取这个指针指向的内存中的值称为dereference,这个的中文翻译叫啥我也不知道。【惭愧】,哈哈。dereference
其相对于内存空间的表示以下:
特别提醒:这里千万千万不要钻进变量名x, ptr的牛角尖里面,不要去思考这些变量名存储在哪里,变量名仅仅是一块内存空间的代号名字而已,咱们应该关心的是这些变量名相对应的内存地址。根据上面的分析能够看出,指针变量和任何变量在内存中的形式是相同的,仅仅在于其存储的值比较特殊而已。
三:引用在内存中的结构和原理
引用(reference)在C++中也是常常被用到,尤为是在做为函数参数的时候,须要在函数内部修改更新函数外部的值的时候,能够说是引用场景很是丰富。但程序员通常很难或者不注意分析reference和pointer,只是知道怎么应用而已,而不去具体分析这个reference。下面我就来简单的分析一下这个reference。首先咱们必须明确的一点就是:reference是一种特殊的pointer。从这能够看出reference在内存中的存储结构应该跟上面的指针是同样的,也是存储的一块内存的地址。例如reference的定义以下:
int x = 5; int &y = x;
reference 和 pointer主要有如下3中不一样点:
1)reference不须要dereference便可直接获取到指向的内存空间的值。例如上例中,直接y就能够获取reference y所指向的内存空间的值,而不须要*y来获取。
2)reference的赋值操做也不须要取地址符来赋值,能够直接经过变量名,例如上例中,int &y = x, 而不须要 int &y = &x;
3) reference 在申明的时候就必需要有初始值,并且reference变量指向的内存地址是不能变化,不像pointer那样能够很灵活的从新指向其余地址。
reference和pointer在内存中的结构和关系以下图所示:
四:指针在Array中的应用和注意事项
在C++中,一个Array类型的变量arr, 其实本质是一个指向数组第一个元素的指针。字符串string在C++中其实就是一个char类型的array,例如:char arr[] = {'a','b','c','d','e','\0'};这就是表示的一串字符串“abcde”,其中arr[0],arr[1], arr[2]..........之间相差的数值可能并不必定是1byte, 要根据这个数组的类型来判断,compiler会自动判断它们之间的相差值的; 另外在c++中字符串也能够用string literals(求大神翻译)的方式表示,即:char *arr2 = "abcde"; 可是经过string literal方式表示的字符串是read only的,不能修改的, 例如:*(arr2+1)= 'f'; 这句语句会产生error的。其在内存中的表现形式以下图所示:
五:指针不能dereference的状况
但一个指针的值是invalid的时候,那么这个指针是不能dereference的。那么到底哪几种状况是invalid的呢?主要有如下几种状况:
1)当这个指针的值是NULL的时候,这个指针是不能dereference的。由于指针为NULL,即表示这个指针指向内存地址为0的地址块,内存地址为0的内存空间是没有值的,因此是不能dereference的; 例如:int *ptr = NULL; cout<<*ptr<<endl; 是错误的。
2)当某个指针被deallocte或者某个指针所在的内存空间被erase了的话,那么这个指针也是不能被dereference的;例以下面的代码:
int *function(int a){ int temp = 5; return &temp; }
上面的代码返回的指针也是不能dereference的,由于temp出了做用域后会被系统回收这一块空间,temp所占的内存空间已经被erase了,因此它返回的指针是一个指向被erase了的内存空间。也是不能dereference的,不然会出错。编译阶段会给出警告,在runtime的时候,若是dereference是会有error的。
好了C++的指针(pointer)和引用(reference)就先总结到这里了。
若是有什么问题欢迎你们的留言或者建议。谢谢