在 C 中将指针变量作为函数参数而不是变量地址传递有什么问题?

问题描述

我知道如果我将 &a 作为参数传递给 fun ,在 fun 执行后我会得到 *p =20 的结果.现在在下面的代码中看到p是作为参数传递给函数fun的指针变量。但是编译后我得到的结果是 *p =10 而不是 20

传递指针变量 p 而不是 a 的地址,即 &a 来运行 fun 有什么问题?

#include <stdio.h>
int a = 10,b = 20;
void fun(int *p)
{
    p = &b;
}
int main()
{
    int *p = &a;
    fun(p);
   //fun(&a);

    printf("%d\n",*p);
    return 0;
}

解决方法

函数参数p

void fun(int *p)
{
    p = &b;
}

是函数的局部变量。函数处理传递给函数的指针值的副本

fun(p);

所以在函数内部,改变的是它的局部变量。

您可以想象该函数及其调用方式如下(为了清楚起见,我将函数参数重命名为 ptr

fun(p);

//...

void fun( /* int *ptr */ )
{
    int *ptr = p;
    ptr = &b;
}

如您所见,原始指针 p 未更改。

如果你想改变指针,你需要通过引用传递它。在这种情况下,函数看起来像

void fun( int **p)
{
    *p = &b;
}

在main中它被称为

fun( &p );

在这种情况下,指针 p(而不是其值的副本)确实会在函数中发生变化。

这是一般规则,如果您想更改函数中的对象,您需要通过引用将其传递给函数。在 C 中,通过引用传递意味着通过指向对象的指针间接传递对象。在这种情况下,取消引用指针,您将获得对原始对象的直接访问。

,

main 和 fun 中的指针标识符 p 不一样,即不指向同一个对象。 如果在 fun() 中分配给 p,则实际上什么都不做。 局部参数 p 的值会在 return 上丢失。

,

p 中的函数参数 funp 中的变量 main 在内存中是不同的对象,更新一个不会影响另一个。

如果您通过 &a,它似乎可以工作,因为您在调用 main:p 之前将 &a 初始化为 funmain:p 根本没有更新。

要做你想做的事,你必须将一个指针传递给p

void fun( int **p )
{
  *p = &b;
}

int main( void )
{
  int *p = &a;
  fun( &p );
  printf( "%d\n",*p );
  return 0;
}