美文网首页
搞不清白的指针啊啊啊啊

搞不清白的指针啊啊啊啊

作者: 里里角 | 来源:发表于2018-08-10 22:41 被阅读3次

    1、一级指针和二级指针

    #include <iostream>
    using namespace std;
    
    void fun(int *p)
    {
        int b=100;
        *p=&b; //*p=5;
    }
    
    int main()
    {
        int a=10;
        int *p;
        p=&a;
        cout<<*p<<endl;
        fun(p);
        cout<<*p<<endl;
        return 0;
    }
    

    在传递一级指针时,只有对指针所指向的内存变量做操作才是有效的;
    void fun(int *p),指针参数p的副本为_p,编译器使_p=p,_p和p指向相同的内存空间,如果在函数内修改了_p所指向的内容,就会导致p的内容也做相应的改变;但如果在函数内_p申请了新的内存空间或者指向其他内存空间,则_p指向了新的内存空间,而p依旧指向原来的内存空间,因此函数返回后p还是原来的p。这样的话,不但没有实现功能,反而每次都申请新的内存空间,而又得不到释放,因为没有将该内存空间的地址传递出来,容易造成内存泄露。

    #include <iostream>
    using namespace std;
    
    void fun(int **q)
    {
        int b=100;
        *q=&b;
    }
    
    int main()
    {
        int a=10;
        int *p;
        p=&a;
        cout<<*p<<endl;
        fun(&p);
        cout<<*p<<endl;
        return 0;
    }
    

    在传递二级指针时,只有对指针的指向做改变才是有效的;
    void fun(int **p),如果函数参数是指针的地址,则可以通过该参数p将新分配或新指向的内存地址传递出来,这样就实现了有效的指针操作。


    二级指针在链表中的使用
    在链表或者树的操作中,也需要用到二级指针,
    比如创建链表的头指针:
    在初始化链表函数中,传入头指针,并在函数中为该指针分配空间,此时就应该使用二级指针,如void initLinklist(Node **head);
    而在添加删除结点的过程中,我们并没有改变函数参数指针的指向,而是通过传入的指针如Node *head,找到要删除结点的位置,并未对该指针做改变,因此退出函数后,该指针无影响。


    指针和引用
    ☆指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。

     int m;
     int &n = m;
    

    1、引用 “从一而终”,只能在定义时被初始化一次,且此时必须初始化,之后不可变。
    2、引用没有 const,指针有 const,const 的指针不可变。
    3、引用不能为空,指针可以为空。“不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。”

    引用的主要功能是传递函数的参数和返回值。
    引用存在的意义:“用适当的工具做恰如其分的工作”。指针能够毫无约束地操作内存中的如何东西,尽管指针功能强大,但是非常危险。

    总的来说,在以下情况下你应该使用指针,一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。
    还有一种情况,就是当你重载某个操作符时,你应该使用引用。

    相关文章

      网友评论

          本文标题:搞不清白的指针啊啊啊啊

          本文链接:https://www.haomeiwen.com/subject/ysokbftx.html