输出是什么,为什么函数中的指针不影响代码?

what is the output and why the pointer in function does not affect the code?

提问人:nh96 提问时间:5/16/2020 最后编辑:RobertS supports Monica Cellionh96 更新时间:5/17/2020 访问量:223

问:

为什么 OP 是 20 ??不是 10 ?我认为 op 应该是 10,但我不知道发生了什么?你能一步一步地解释一下吗

void fun(int *ptr)
{
    int q=10;
    ptr=&q;
}

int main()
{
    int r=20;
    int *p=&r;
    fun(p);
    printf("%d",*p);
    return 0;
}
C 函数 指针 参数 按值传递

评论

2赞 kaylum 5/16/2020
1. 更改局部变量,而不是调用方的变量。2.也是一个局部变量,函数退出后不再存在。尝试访问调用方中的该内存是未定义的行为。ptr=&qq
2赞 David C. Rankin 5/16/2020
C 是按值传递的,因此从您尝试更改 address-held-by 而不是原始地址的值(例如)接收指针的副本。对副本所持有的地址所做的更改将在功能返回时丢失。funmain()ptrptr*ptr = q;
0赞 Daniel Walker 5/17/2020
@kaylum,你想把它作为答案发布吗?

答:

1赞 MikeCAT 5/16/2020 #1
  • 函数参数的值是从调用方传递的内容的副本。在被调用方中修改不会影响调用方的局部变量。
  • 非静态局部变量将在退出其作用域时消失。因此,在此之后,不得取消引用指向它们的指针。

要获得 10,您的代码应为:

#include <stdio.h>

void fun(int **ptr) /* pass a pointer to modify caller's local variable */
{static int q=10; /* add static to prevent it from vanishing */
*ptr=&q; /* dereference the pointer */
}

int main()
{int r=20;
int *p=&r;
fun(&p); /* pass the pointer */
printf("%d",*p);
return 0;
}
1赞 Déjà vu 5/16/2020 #2

这是 和 (地址基于实例pr

 ----------------      ----------------      ----------------
 | r         20 |      | p       1234 |      | q         10 | 
 ----------------      ----------------      ----------------
 ^                     ^                     ^
 |_ Address of r       |_ Address of p       |_ Address of q
    = 1234                = 9876                = 12121

fun()

void fun(int *ptr) {
   int q = 10;
   ptr = &q;
}

您提供 as (ie),然后设置为pptr1234ptrq

fun:  ptr = 12121

然后乐趣结束了,并随之消亡,记忆没有改变ptrr

要更改某些内容,您必须传递该内容的地址。即使它是一个指针。

将地址提供给pfun

fun( &p );

并更改为接受指向指针的指针fun()

void fun(int **ptr) {  // <== pointer to pointer
   int q = 10;
   *ptr = &q;          // <== change r indirectly
}

这里,有指针的地址,即ptrp9876

*ptr = &q; // changes the value of `r`
0赞 RobertS supports Monica Cellio 5/17/2020 #3

这主要是因为两个原因:

  1. pin 和 in 是两个不同的指针,并且main()ptrfun()
  2. 传递,而不是按引用传递。p

在函数调用中:

fun(p);

你只是按传递;意味着它将 的地址(实际上是 的值)传递给 。prpptr

使用 in 时,只需将 的地址分配给 ,但不能分配给 。ptr = &q;fun()qptrp

因此,取消引用的输出为:p

printf("%d",*p);

当然是,因为仍然指向 -> 的值没有改变。20prp


如果您改为通过引用传递并声明为指向指针 () 的指针,加上限定符(因为函数局部变量将在函数执行一次后被销毁):pptr**qstaticauto

void fun(int **ptr)            // ptr is declared as pointer to pointer to int.
{
    static int q = 10;         // q is static -> It won´t get destroyed after returning from `fun()`.
    *ptr = &q;                 // dereferencing ptr to assign the address of q to p.
}

int main()
{
    int r = 20;
    int *p = &r;
    fun(&p);                   // Notice the `&` to gain the address of `p`, not `r`.
    printf("%d",*p);
    return 0;
}

输出将与我们实际分配的地址一样。10qp

顺便说一句:从调用方引用限定的函数局部变量被认为是一种糟糕的编程风格。我只是出于教育目的向您展示了这个,并展示了您提供的代码的区别。static

尝试通过被调用函数内部传递的指针,在这里,使用被调用函数中对象的实际值来分配一个对象,这里是 。rptrq