将指针传递给函数值不变

时间:2017-06-13 20:02:22

标签: c pointers

#include<stdio.h>

void foo(int*);
int main()
{
    int i = 97, *p = &i;
    foo(p);
    printf("%d ", *p);
    getch();
}

void foo(int *p)
{
    int j = 2;
    p = &j;
    printf("%d ", *p);
}

输出为2 97 为什么不2 2? 指针p现在保存j的地址,为什么要打印97?

4 个答案:

答案 0 :(得分:3)

您可以通过以下方式想象函数调用及其定义。为清楚起见,我将函数参数重命名为q

foo(p);

void foo( /*int *q*/ )
{
    int *q = p;
    int j = 2;
    q = &j;
    printf("%d ", *q);
}

正如可以看到的那样,函数参数(在这种情况下是q)是函数的局部变量,它由参数的值初始化(在本例中是参数{{1}的值) })

因此局部变量(p)的任何更改都不会影响原始参数(q)。

退出函数后,局部变量将不会存活。

如果要更改参数本身,则应通过引用传递它。例如

p

但是在退出函数后,原始参数/变量void foo( int **p ) { int j = 2; *p = &j; printf("%d ", **p); } 将无效,因为它存储函数p的非活动局部变量的地址。

因此,尝试访问函数的局部变量j占用的内存会导致程序的未定义行为。

您可以通过将局部变量j声明为具有静态存储持续时间来使程序正确。例如

j

并调用函数

void foo( int **p )
{
    static int j = 2;
    *p = &j;
    printf("%d ", **p);
}

答案 1 :(得分:1)

foo中,您为p分配一个新值。但是,这是pmain值的副本,因此更改在主屏幕中不可见。

如果您取消引用 p,那么它会更改main中i的值:

void foo(int *p)
{
    *p = 2;
    printf("%d ", *p);
}

答案 2 :(得分:1)

p

只是更改局部变量p的值。这对调用者的p变量(因为p是按值传递)或*p = j; 之前指向的变量(因为你没有间接通过它)没有影响。如果要更改呼叫者的数据,请写:

_ViewStart.cshtml

答案 3 :(得分:0)

逐行浏览上述代码。在这里我写了评论,因为控制遍历每一行......

#include<stdio.h>

void foo(int*);
int main()
{
    int i = 97, *p = &i;   //Lets assume i has address 2000  
    foo(p);                //p contains 2000 which is passed to foo. go to foo at 1.
    printf("%d ", *p);    // when control comes back no change to p it 
                          //still points to 2000 which stores 97 
    getch();
}

void foo(int *p) 1: // in foo another local variable p is created. 
                   //Let's call this lp. lp has now address 2000. i.e lp 
                   //and p both point to i but one locally exists in a 
                   // function and will be destroyed when control comes out 
                   // of the function 
{
    int j = 2;
    p = &j;        // now local p i.e lp points to another var j 
                   //  address. Suppose lp has address 3000 now.  
    printf("%d ", *p);  //val at address in lp is 2
}