C++指针、引用知多少?

 

     上午搞了一个小程序,test半天都没有获得想要的结构,原来是递归的时候没有注意的循环的问题,结果直接死循环了。催了...看来当程序出现问题的时候,首先要整理的是算法思路是否有问题,其次是算法的实现,是否容易进入死循环,边界条件是否出现错误。算法

       好的,废话很少说,继续整理。小程序

       指针数组

       指针这东西,要是搞复杂了,这还真是高深莫测,你不认真研读研读还真不行,真心以为搞程序一浮躁,各类bug就都出来了。安全

       指针的声明:函数

1     int x=20; 2     int *p,q; 3     int* m,n; 4     p=&x; 5     q=x; 6     m=&x; 7     n=x; 8     cout<<*p<<" "<<q<<" "<<*m<<" "<<n;

     我想,这应该就是最简单的声明了吧,p是一个指针,而且是一个指向x的指针。那么若是cout<<p;会获得什么结构呢?其实p自己保存的是一个地址。而且保存的是x所存储的地址。优化

   不信的话能够改为如下语句:spa

1     int x=20; 2     int *p,q; 3     int* m,n; 4     p=&x; 5     q=x; 6     m=&x; 7     n=x; 8     cout<<p<<" "<<&x<<" "<<m;

   他的输出结果就是:3d

  

   因此,在这里咱们已经对指针有一个初步的认识,指针其实就是一个地址的东西,只不过这个地址保存的是咱们所指向的值得地址。指针

   空指针void*code

   咱们通常的指明了指向类型的指针都是只能指向该类型的,好比说上面提到的p指针,它只能指向Int类型。可是void*是怎么样的呢?

   其实void*指针能够指向任何类型,固然也能够指向int。若是咱们下面代码会出现什么状况呢?

1     void *y; 2     y=&x; 3     cout<<y;

   实际上咱们会发现,y输出的是地址,而且和上面的P,m的地址是一致的,实验发现,我上面的说法是对的。

   很显然,若是仅仅获得一个void*指针是没有太大意义的,那么咱们怎么把他转化成原有的int*,甚至转化成int呢?

   这里咱们须要显示转化,(int*)y,转化成整数的话就是*((int*)y);

   因此如今咱们应该知道了当函数的返回值是void和void*是有多么大的不一样了吧。void*是返回一个特殊的指针类型。

   多重指针

   这里说的多重指针在不少地方也称为指向指针的指针。

   咱们是否是常常会遇到int **m;这种状况呢,其实他就是一个多重指针。

   仍是上面那个例子,咱们如下定义一个多重指针

1     int **z; 2     z=&p; 3     cout<<"多重指针"<<p<<*z;

   p咱们知道会输出x的地址,那么*z又是上面呢,z是一个指向指针p的指针。那么z保存的是p的地址,*z理所固然的应该保存的也是x的地址。见下图

   了解了这个以后,那么咱们就很容易的知道了,动态二维数组的建立过程了,就是一个指向指针的指针,二重指针嘛,so easy。

   函数指针

   咱们常常会须要动态的调动几个函数的某一个,若是咱们只是if else那代码量可能有时候会比较大,有没有能够在函数参数中直接传递一个函数呢?

   答案是不可能的,可是咱们有一种方式能够实现,那就是经过指针函数来讲。

   typedef void (*pf)(int &m,int *n);

   这是什么意思呢?他的意思就是说pf是一个指针函数,他能够指向任意的返回值为void,而且参数是int &m和int *n的函数。

    一样咱们声明pf f;就能够把f做为一个函数了,也能够把f当作一个参数传到函数体中了。具体例子见下面。

 1 void swap(int &m,int *n); //定义一个有两个参数的函数swap
 2 typedef void (*pf)(int &m,int *n);//  3 void print(int &m,int *n,pf x);//定义一个能传递指针函数的函数
 4 int _tmain(int argc, _TCHAR* argv[])  5 {  6     int m=6,q=20;  7     pf f=swap;  8     int* n=&q;  9  f(m,n); 10     cout<<&m<<*n; 11  print(m,n,f); 12     system("pause"); 13     return 0; 14 }

    一样的道理,咱们也能够返回一个指针函数,只不过返回类型是pf。它返回的实际类型应该是 void (*)(int&,int*);解释起来就是一个指向两个传输的函数指针。

   咱们能够定义一个 pf fun();他就返回的是函数指针了。

    引用&

    实际上引用能起到的做用,*不少时候也可以起到,那为何咱们还常常说,要尽可能使用引用呢?最大的优势就是指针更安全。固然某些状况下例外。

    引用能够认为是一个别名,而指针则是一个实体,虽然他们都有地址的概念在里面。

    这里主要描述一下引用和指针的不一样之处。

     一、指针是能够从新指向另一个对象,而引用不行,引用一旦绑定那就不能再绑定其余了,引用的这种性质有一点嫁鸡随鸡嫁狗随狗的意味在里面。这对男人是否是更安全呢?O(∩_∩)O哈哈~

     二、指针能够是空指针,可是引用不能是空引用啊,因此引用都是必须初始化的。

     三、指针是指向一个实体(程序为指针变量分配内存区域),而指针则是一个别名,这个能够怎么理解呢?咱们经过sizeof(指针)和sizeof(引用)能够知道,前者是指针的大小,通常为4,然后者则是引用对象的大小,也就是说,若是对一个字符串长度为100的字符串进行引用sizeof是100哦,而指针仍是4.

    四、若是须要返回动态分配的对象或者内存,应该使用指针,引用颇有可能引发内存泄露问题。

    固然还有其余的一些不一样,可是整体来讲都是由以上衍生出来的。

    其实引用本质上来讲是一种指针,只不过编译器进行了优化(因此指针更加灵活),因此引用具备指针的特色,又更安全。

 

 

     版权全部,欢迎转载,可是转载请注明出处:潇一

相关文章
相关标签/搜索