One example they get double pointer

In a recent write list when it came to questions about pointers, in the course of the study finally understand the meaning and use of the use of double pointer in the function parameter in.

We start talking about writing a function. This function requires the insertion of a node at the head of a linked list, this list is not the first node, and requires the return value is void . That is in the function to complete the modification of the list head pointer.

The beginning of my writing is this:

typedef struct ListNode{
    int val;
    struct ListNode* next;
}ListNode;

void myLinkedListAddAtHead(ListNode* obj,int val){
    ListNode *List=obj;
    ListNode *Temp=malloc(sizeof(ListNode));
    if(temp==NULL){
        prinf("Out of space!");
    }
    else{
        Temp->val=val;
        Temp->next=List;
        obj=Temp;
    }
}

Readers can start to think of this function is a problem. Let's put aside the example aside, look at another simple example. Now to design a switching function values ​​a, b of.

The first was written by two variables direct transmission parameters, exchanged in the parent function in the print.

void Swap(int a,int b)
{
    int tmp = a;
    a = b;
    b = tmp;
}
 
int main()
{
    int a=1;
    int b=2;
    printf("a=%d,b=%d\n",a,b);
    Swap(a,b);
    printf("a=%d,b=%d\n",a,b);
    return 0;
}

The output is:

1,2

2,1

The result is not successful exchange. We look at one of the memory allocation and variable exchange what went wrong.

Note that this picture of black and red variables a, b, although the same name, but it is two different memory space . Because the function does not return a value, so we just changed the internal function of the red values of a, b, and does not change the main function black a, b values. Therefore, when printing in the main function values of a, b and does not change.

So if we want to succeed, then the output, the output will be carried out inside the function:

void Swap(int a,int b)
{
    int tmp = a;
    a = b;
    b = tmp;
    printf("a=%d,b=%d\n",a,b);//在函数中输出
}
 
int main()
{
    int a=1;
    int b=2;
    printf("a=%d,b=%d\n",a,b);
    Swap(a,b);
    return 0;
}

The output is:

1,2

2,1

The result is a successful exchange. Of course, black a, b variables yet to exchange, we just print the value of variable red after the exchange.

So we just want to exchange values ​​of a, b, how to do it? Since we naturally think of just black and red are two storage resulting in no success, then we let them into the same memory space is not on line yet? So the second approach is to address the variable passed to the function.

void Swap(int *p1,int *p2)
{
    int *tmp = p1;
    p1 = p2;
    p2 = tmp;
}

int main()
{
    int a=1;
    int b=2;
    printf("a=%d,b=%d\n",a,b);
    Swap(&a,&b);
    printf("a=%d,b=%d\n",a,b);
    return 0;
}

The output is:

1,2

1,2

Or not. This is why? Let's analyze the case of memory allocation.

Although we originally introduced to address, but the internal function simply exchanged variable address pointer, a, b values ​​remain unaltered. So we have to be exchanged is not a pointer, but the pointer to the value at the address (* p1 and * p2).

void Swap(int *p1,int *p2)
{
    int *tmp;
    *tmp = *p1;
    *p1 = *p2;
    *p2 = *tmp;
}

int main()
{
    int a=1;
    int b=2;
    printf("a=%d,b=%d\n",a,b);
    Swap(&a,&b);
    printf("a=%d,b=%d\n",a,b);
    return 0;
}

During operation the program has crashed. The original tmp is a wild pointer, int * tmp is a random address value stored in the computer system. Direct modification will cause unpredictable errors. So we directly use a variable of type int tmp instead of * tmp like that shown below.

void Swap(int *p1,int *p2)
{
    int tmp;
    tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
}

int main()
{
    int a=1;
    int b=2;
    printf("a=%d,b=%d\n",a,b);
    Swap(&a,&b);
    printf("a=%d,b=%d\n",a,b);
    return 0;
}

After going around in circles, let us return to the original question, you find the problem yet? Yes, in the obj parameter is equivalent to the first written in red variables a, he just saved a copy of the pointer points to the first node in the original list . That opened up space for an internal function pointer size, then copy the address of the list head to this space a. The operation of the internal space of the original function is completely independent of the head of the list.

Therefore, in accordance with the practice in the previous example, we have here ListNode * as int of view, you will find that we should pass a ListNode * address, namely ListNode ** a. This is the origin of the double pointer, we want to change the address of a pointer. Our final wording is:

typedef struct ListNode{
    int val;
    struct ListNode* next;
}ListNode;

void myLinkedListAddAtHead(ListNode** obj,int val){
    ListNode *List=*obj;//obj存储的是指向链表第一个节点的指针的地址,List存储obj地址中保存的值,即链表第一个节点的地址
    ListNode *Temp=malloc(sizeof(ListNode));
    if(temp==NULL){
        prinf("Out of space!");
    }
    else{
        Temp->val=val;
        Temp->next=List;
        *obj=Temp;//将新节点的地址赋值给obj指向的地址,即赋值给指向链表第一个节点的指针
    }
}

Said winding is still very words, on the map:

Finally done, now we finally understand the role of the double pointer. However, if allowed to return a pointer, in fact, things could have been easier, we also do not use a double pointer.

Guess you like

Origin www.cnblogs.com/lxy764139720/p/11569966.html