【问题标题】:what is the output and why the pointer in function does not affect the code?输出是什么,为什么函数中的指针不会影响代码?
【发布时间】:2020-09-01 22:19:50
【问题描述】:

为什么 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;
}

【问题讨论】:

  • 1. ptr=&q 更改 local 变量而不是调用者的变量。 2.q也是一个局部变量,函数退出后不再存在。试图在调用者中访问该内存是未定义的行为。
  • C 是 pass-by-value 所以fun 接收到来自main() 的指针的副本 在您尝试的ptr并更改 address-held-by ptr 而不是 value-at-the-original-address(例如 *ptr = q;)。对副本保存的地址所做的更改在函数返回时丢失。
  • @kaylum,你想把它作为答案发布吗?

标签: c function pointers parameters pass-by-value


【解决方案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;
}

【讨论】:

    【解决方案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;
    }
    

    你提供pptr(即1234),然后将ptr设置为q的地址

    fun:  ptr = 12121
    

    然后乐趣结束,ptr 随之消亡,r 的内存没有改变

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

    p的地址提供给fun

    fun( &p );
    

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

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

    这里ptr有指针p的地址,即9876

    *ptr = &q; // changes the value of `r`
    

    【讨论】:

      【解决方案3】:

      这主要是因为两个原因:

      1. p in main()ptr in fun() 是两个不同的指针,而
      2. 您通过而不是引用传递p

      在函数调用处:

      fun(p);
      

      你只需通过传递p;意味着它将r的地址(p的实际值)传递给ptr

      使用fun() 中的ptr = &amp;q;,您只需将q 的地址分配给ptr,而不是p

      因此,解引用p at 的输出:

      printf("%d",*p);
      

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


      如果您改为通过引用传递 p 并将 ptr 声明为指向指针 (**) 的指针,加上限定 qstatic 限定符(因为函数本地 automatic 变量将被破坏函数执行一次后):

      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;
      }
      

      输出将是10,因为我们实际上将q 的地址分配给了p

      附带说明:从调用者那里引用static-qualified 函数局部变量被认为是不好的编程风格。我只是出于教育目的向您展示了这个,并展示了您提供的代码的不同之处。

      尝试分配一个指向调用者的对象,这里是 f.e. r,由被调用函数内部传递的指针,此处为ptr,与被调用函数中对象的实际值,此处为q

      【讨论】:

        猜你喜欢
        • 2014-07-28
        • 1970-01-01
        • 2019-07-17
        • 2014-05-16
        • 1970-01-01
        • 2018-12-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多