为什么以下程序的输出2 97而不是2 2?

时间:2018-01-04 17:42:36

标签: c

在下面的代码中,为什么当我们调用foo函数时,j的地址是否被p覆盖?

[Theory]
    [InlineData("2000-01-02", "2000-02-01")]
    public void TestSynchronizeMissionStaffing_PeriodNoMatch(params string[] dateStrings)

4 个答案:

答案 0 :(得分:4)

您正在使用foo进行打印 - 这会将p设置为2,然后您打印到p的打印件,该打印件仍设置为97 in那范围。 foo未在全球范围内设置p

答案 1 :(得分:2)

因为p中的main是函数中的p之外的另一个变量。因此,即使在函数内部更改ppmain的值仍然相同,仍然指向97.

更多细节:

    int main()
    {
        int i = 97, *p = &i;  // i is 97 and p points to i
        foo(&i);
        printf("%d ", *p);    // This prints what p points to, i.e. 97
    }
    void foo(int *p)
    {
        int j = 2;   // Here p still points to i in main
        p = &j;      // Now p points to j, i.e. the value 2
        printf("%d ", *p);  // So this prints 2
    }

重复一遍:重要的是p中的mainp中的foo是两个不同的变量。

如果您希望程序打印2 2,可以将功能更改为:

    void foo(int *p)
    {
        int j = 2;
        *p = j;     // Change this line. This will change i in main
                    // and thereby also the value that p in main points to
        printf("%d ", *p);
    }

答案 2 :(得分:0)

以下是步骤:

    int main()
    {
        int  i = 97;
        int* p = &i;        // 1. p points to i, i is 97.
        foo(&i);            // 2. Pass the address of i by value.

        printf("%d ", *p);  // 6. Print the value of i as neither p nor i have not changed inside foo().
    }

    // I've renamed the parameter name from p to q for clarity. q is local to
    // foo() only; changes made to q are only visible within foo().
    void foo(int* q)
    {                      // 3. q contains a copy of i's address.
        int j = 2;
        q     = &j;        // 4. q is set to the address of j. 

        printf("%d ", *q); // 5. Print the value of j.
    }

如果您在*q = 2内完成foo(),则会将i的值更改为2。这是因为q包含i的地址。

答案 3 :(得分:0)

p中的main是内存中与p中的foo不同的对象。写入一个对另一个没有影响。如果您希望foo更新pmain的值,则必须将指针传递给p

#include <stdio.h>
int main()
{
    int i = 97, *p = &i;
    foo(&p);
    printf("%d ", *p);
}

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

警告 - 执行此操作将调用未定义的行为,因为p将指向不再存在的对象 - 一旦foo退出, j已不存在,p将是无效的指针。您可能获得您期望的输出,或者您可能不会。

为了使函数能够写入参数,必须传递一个指向该参数的指针:

void foo( T *ptr )
{
  *ptr = new_value(); // updates the thing ptr points to
}

void bar( void )
{
  T var;              // var is an instance of T
  foo( &var );        // have foo update the value of var
}

任何非数组类型T 都是如此,包括指针类型。如果我们用指针类型T替换P *,我们得到

void foo( P * *ptr )
{
  *ptr = new_value(); // updates the thing ptr points to
}

void bar( void )
{
  P * var;            // var is an instance of P *
  foo( &var );        // have foo update the value of var
}

语义完全相同 - 唯一改变的是var以指针类型开头。

数组类型的事情变得奇怪,我们还没有进入。