【问题标题】:Why doesn't fun(int *p) alter the value of the pointer? [duplicate]为什么 fun(int *p) 不改变指针的值? [复制]
【发布时间】:2018-01-08 18:54:37
【问题描述】:
void fun(int *p) 
{ 
  int q = 10; 
  p = &q; 
}     

int main() 
{ 
  int r = 20; 
  int *p = &r; 
  fun(p); 
  printf("%d", *p); 
  return 0; 
}

我对指针有所了解,但我猜printf 应该显示 10,尽管网站的编译器和其他编译器说该值仍然是 20。

谁能解释一下原因?

fun() 对指针p 有影响吗?为什么或为什么不?

【问题讨论】:

  • p本地
  • fun(int *p) 确实p = &q;改变指针值。然而,fun() 中的 p 不是 main() 中的 p
  • 这个问题的 8 个答案?真的吗?
  • 感谢尤金,这让事情变得一清二楚。变量共享名称,而不是范围。

标签: c pointers


【解决方案1】:

如果p 是函数参数,则函数体内的p = something 不会改变调用处的值。 p 是不是指针都没关系。

您将它与 *p = somethingp[foo] = something 混淆了。

【讨论】:

    【解决方案2】:

    指针按值传递,变化被本地化为fun()。如果您要更改 *p 会被 main 看到,但不会更改指针本身。

    【讨论】:

      【解决方案3】:

      fun() 中的变量“p”是堆栈上的本地指针。您将 p 重新分配为指向 q(也是一个本地指针),但是当该函数存在时,堆栈帧被弹出并且值和指针消失。

      如果你想让fun()实际修改调用函数中变量的值,试试换行:

      p = &q;
      

      成为:

      *p = q;
      

      这实际上将q (10) 的值写入p 指向的地址,而不是重新分配 p 指向别的东西。

      【讨论】:

        【解决方案4】:

        您将指向函数的指针的副本作为参数提供。所以这个功能不能改变原来的。
        你可能想给指针一个指针,这使函数能够改变指向的指针。

        void fun(int **p) 
        { 
          static int q = 10; 
          *p = &q; 
        }     
        
        int main() 
        { 
          int r = 20; 
          int *p = &r; 
          fun(&p); 
          printf("%d", *p); 
          return 0; 
        }
        

        然而,这非常冒险,更不用说疯狂了。
        在我的示例中,我将局部变量更改为静态,以避免返回指向局部变量的指针的最可怕后果。
        您可能必须在相当大的范围内重新设计,才能为您正在尝试的任何事情找到一个干净的解决方案。

        【讨论】:

        • 我不会说这很疯狂,有趣的部分是在我从中获取的网站的“讨论”部分中,他们传递了对指向 fun 函数的指针的引用,并且fun 函数将双指针作为参数。这与他们最初的问题不同。
        【解决方案5】:

        函数中的 p 获取 main 中 p 的值,从而获得 r 的地址,然后在函数中将 q 的地址分配给函数中的 p。但是 main 中的指针 p 完全不受 fun 中的指针 p 的影响,因此 main 中的指针 p 仍然具有变量 r 的地址。显然现在你知道为什么它会打印 20。

        【讨论】:

          【解决方案6】:

          如果您在函数中的代码是:

          *p = q;
          

          这会将 p 指向的地址内的值更改为变量 q 所保存的值(它是函数的本地变量)。

          【讨论】:

            【解决方案7】:

            在 C 中,传递给函数的值是按值传递的;也就是说,它们被复制到函数中。 fun 中的 pmain 中的 p 的副本。此副本已更改,然后在 fun 返回时被丢弃,main 中的 p 保持不变。

            顺便说一下,如果它按您的预期工作,printf 可能不会打印10fun 中的变量 q 是本地变量,并且在 fun 退出时立即销毁。在实践中,这通常意味着它仍在内存中,但在堆栈结束之后*;对printf 的调用可能会用printf 的一些参数或其他本地数据覆盖q


            * 实际上,由于它从未使用过,只是将其地址设为p,而后者又从未使用过,因此实际上编译器会完全优化它,除非您使用-O0

            【讨论】:

              【解决方案8】:

              在函数 fun 之外(在 main 内部),变量 'q' 不存在,因此它的地址不存在于 p 中。当您在主函数中取消引用“p”时,它的地址为“r”而不是“q”。如果您在 fun 中取消引用“p”,它将具有“q”的地址并显示 10。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2021-03-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-07-02
                • 1970-01-01
                • 2012-04-13
                相关资源
                最近更新 更多