【问题标题】:Functions and pointer to pointers函数和指向指针的指针
【发布时间】:2011-04-26 07:08:37
【问题描述】:

我一直试图在被调用函数中创建一个指针变量,并以某种方式将它指向的值传递给主函数。我写了一些示例程序,但我似乎仍然遗漏了一些东西。挑战是使用指向指针的指针来实现这一点。这是我编写和测试的代码。我认为遗漏了一些明显的东西,你们能指出它吗?谢谢。

        int one(int ***ptr)
        {
            static int *p,**pp,b=10;
            p=&b;
            pp=&p;
            ptr=&pp;
            printf("b:%d\tp:%d\tpp:%d\n",b,*p,**pp);
            printf("Sub Ptr:%d\n",***ptr);
            printf("Address of ***ptr:%d\n",&ptr);
            return 32;
        }
        int main(int argc, char *argv[])
        {
              static int ***ptr;
              int a=200,*b,**c;
              b=&a;
              c=&b;
              ptr=&c;
              printf("Main Ptr:%d\n",&ptr);
              a=one(ptr);
              printf("Main Ptr:%d\n",&ptr);
              printf("Main Ptr:%d\n",***ptr);
              system("PAUSE");
              return 0;
        }

我得到 32 的输出,这是函数的返回值。是否可以获得被调用函数中指向的 10 的值。

我也尝试过全局声明,但也可以正常工作。我想维护本地声明,看看它是否可能......

【问题讨论】:

    标签: c pointers function


    【解决方案1】:

    我认为您误解了指针。您的代码的问题是您没有意识到指针也是“按值传递”,函数中的指针是堆栈上的另一个变量,而不是您在主函数中声明的那个。

    我会用一个更简单的例子,但想法是一样的。

    void changePointerValue (int * ptr) 
    {
        int newValue = 10;
        ptr = &newValue;
    }
    
    int main () 
    {
        int x = 20;
        int * ptr = &x;
        changePointerValue (ptr);
        printf ("After Change: %d\n", *ptr);
    }
    

    你认为它会在 main 函数中输出什么值?那是 10 点吗?

    但不,实际上它会输出 20。

    为什么?让我们看看我们的代码做了什么。在 chagePointerValue(ptr) 行中,计算机将 main 函数中 ptr 的值复制到堆栈上的一个新变量中,我们称之为 ptr' 并将其传递给 changePointerValue 函数。

    所以实际上changePointerValue函数中的ptr是ptr',而不是你在main函数中声明的那个。 changePointerValue的第二行,你给ptr'分配了一个新的内存地址,之后,ptr'因为函数返回而被丢弃。 main函数中的ptr保持不变,即指向x的内存地址。

    如果希望输出为 10,则需要在 changePointerValue 中引用 ptr,并且赋值的意思是“更改 ptr 指向的值”。

    void changePointerValue (int * ptr) 
    {
        int newValue = 10;
        *ptr = newValue;   // Now you are change the content of the memroy cell where ptr is pointed at.
    }
    
    int main () 
    {
        int x = 20;
        int * ptr = &a;
        printf ("Before Change:%d", x); // 20
        printf ("Before Change:%d", *ptr); // 20
        changePointerValue (ptr);
        printf ("After Change: %d\n", *ptr); // 10
        printf ("After Change: %d\n", x); //10
    }
    

    编辑:

    所以,如果你希望它在 main 函数中打印 10,那么正确的方法是在函数中尊重 ptr。但这也会改变主函数中变量a的值。

        int one(int ***ptr)
        {
            ***ptr=10; // Dereference ptr to where it points to. (Varaible a in the main function)
            return 32;
        }
        int main(int argc, char *argv[])
        {
              static int ***ptr;
              int a=200,*b,**c;
              int result;
              b=&a;
              c=&b;
              ptr=&c;
              printf("Main Ptr:%d\n",&ptr); // The memory address of variable ptr.
              result=one(ptr);
              printf("Main Ptr:%d\n",&ptr); // the memory address of variable ptr.
              printf("Main Ptr:%d\n",***ptr); // 10
              printf("Main a:%d\n", a); // 10
              printf("Main result:%d\n", result); //32
              system("PAUSE");
              return 0;
        }
    

    【讨论】:

    • 错字:在你的例子中它必须是 "int *ptr = &x" (不是 &a) ;)
    • 感谢您的指点,我错过了两件事,一是取消引用和堆。
    【解决方案2】:

    您将 ptr 设置为局部变量 (b) 的地址,该地址在函数末尾超出范围。这是未定义的行为。您要么需要分配给***ptr,要么需要分配给malloc 堆上的东西。

    另外,您将 ptr 按值传递给函数。所以对它的任何本地修改都不会反映在main 中。您需要通过指针传递,即您需要一个 int **** 作为参数。

    我真的希望这只是一个学习练习,因为任何超过两个级别的指针通常表明设计确实需要重新评估!

    【讨论】:

    • 我在调用函数“int b=malloc(sizeof(int)); b=10;”中做了这个mod但结果还是一样....这是你的意思还是我误会了?
    • 不,我的意思是p = malloc(sizeof(int)); pp = &b; ptr = &pp; *p = 10;
    • 我通过从堆中取出一些内存来进行更改,但结果仍然相同。 ***ptr 在被调用函数中指向 10,但是当控件返回主函数时,它指向 32。我没有答案,这正在发生。它适用于我尝试过的简单指针示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多