简体   繁体   English

无法在c中取消引用双指针

[英]Unable to dereference double pointer in c

The output of this code is 20 20 10. The first 20 is easy to understand. 此代码的输出为20 20 10.前20个很容易理解。 But I am unable to understand how function change1 and change2 are accessing the variable b. 但我无法理解函数change1change2如何访问变量b。

#include<stdio.h>
int a = 5, b = 10;
void change1(int *p);
void change2(int **pp);
main( )
{
    int x=20, *ptr=&x;
    printf("%d  ",*ptr);
    change1(ptr);
    printf("%d  ",*ptr);
    change2(&ptr);
    printf("%d\n",*ptr);
}
void change1(int *p)
{
    p = &a;
}
void change2(int **pp)
{
    *pp = &b;
}

But I am unable to understand how function change1 and change2 are accessing the variable b . 但我无法理解函数change1change2如何访问变量b

There is a misunderstanding of what change1 does. 有一个什么样的误解change1一样。

It changes where p points to but that change is local to the function. 它会改变p指向的位置,但该更改是函数的本地更改。 It does not change where ptr points to in main since the pointer is passed by value. 它不会改变ptr指向main因为指针是按值传递的。 change1 does not have any code that accesses the variable b . change1没有任何访问变量b代码。 It's not clear to me whey you think it does. 我不清楚你认为它是什么。

In change2 , you are changing where the pointer points to, to b . change2 ,您正在将指针指向的位置更改为b The change affects where ptr points to in main since you are passing the address of ptr to change2 and you are changing where that dereferenced pointer points to. 由于您将ptr的地址传递给change2并且您正在更改解除引用指针所指向的位置,因此更改会影响ptr指向main位置。

In change1, p is a pointer to int that is passed by value. 在change1中,p是一个指向int的指针,它由value传递。 Assigning a value to p in change1 therefore has no effect because p is local to change1. 因此,在change1中为p赋值不起作用,因为p是change1的本地值。 This is the reason for the 2nd 20. 这就是第二次20的原因。

In change2, pp is a pointer to a pointer to int. 在change2中,pp是指向int的指针。 It too is passed by value, but this time dereferencing pp (*pp) gives access to the location of the pointer (ptr), and it is into this location that the address of b (&b) is stored. 它也是通过值传递的,但是这次取消引用pp(* pp)可以访问指针(ptr)的位置,并且在这个位置存储b(&b)的地址。

void change1(int *p)
{
    p = &a;
}

The variable p is assigned with the address of a, but this is only valid within the function. 变量p分配有地址a,但这仅在函数内有效。 p acts as a local variable within the function change1 . p充当函数change1local variable After this function terminates, the pointer ptr would still be pointing at x(=20). 在此函数终止后,指针ptr仍将指向x(= 20)。 This is the reason behind the second 20. 这就是第二次20后面的原因。

void change2(int **pp)
{
    *pp = &b;
} 

But this, is one of the correct ways to make changes to a pointer variable within the function so that it would still be valid outside. 但是,这是对函数中的指针变量进行更改的正确方法之一,以便它在外部仍然有效。 pp acts as a pointer pointing to the original ptr variable. pp充当指向原始ptr变量的指针。 As a result, ptr will end up pointing at b(=10) after change 2 terminates. 结果,在更改2终止后,ptr将最终指向b(= 10)。 This is the reason behind your third 10. 这就是你的第三个10后面的原因。

When you invoke change1() function, you're passing the pointer ptr as an argument. 当您调用change1()函数时,您将指针ptr作为参数传递。 Let's suppose ptr = 0xcafebabe , and obviously *ptr = 20 . 我们假设ptr = 0xcafebabe ,显然*ptr = 20

Under the hood, you're writing the value 0xcafebabe on the stack, and the change1() function will only overwrite this value with &a on the stack frame corresponding to this function. 在引擎盖下,您在堆栈上写入值0xcafebabe ,而change1()函数将仅使用&a此函数对应的堆栈帧上的&a覆盖此值。

In the second case, you're passing a pointer to ptr as an argument. 在第二种情况下,您将指向ptr的指针作为参数传递。 Let's suppose this pointer new_ptr has a value of 0xdeadbeef . 我们假设这个指针new_ptr的值为0xdeadbeef
In this case, *new_ptr = 0xcafebabe and you overwrite 0xcafebabe with &b (hence you are changing where the pointer is pointing . 在这种情况下, *new_ptr = 0xcafebabe ,你用&b覆盖0xcafebabe (因此你正在改变指针指向的位置)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM