函数和指针指针

时间:2010-10-16 10:23:13

标签: c pointers function

我一直在尝试在被调用函数中创建一个指针变量,并以某种方式将其指向的值传递给main函数。我写了一些示例程序,但我似乎仍然遗漏了一些东西。而挑战是使​​用指向指针的指针来实现这一目标。这是我编写和测试的代码。我想我错过了一些明显的东西,你们可以指出它吗?感谢。

        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。

我也尝试了全球宣言,但也努力工作。我想保留当地的声明,看看它是否可能......

2 个答案:

答案 0 :(得分:4)

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

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

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);
}

您认为它在主要功能中输出的价值是多少?那是10?

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

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

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

如果您希望输出为10,则需要在changePointerValue中使用deference 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,那么正确的方法是在函数中使用deference 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;
    }

答案 1 :(得分:1)

您正在将ptr设置为本地变量(b)的地址地址地址,该地址变量超出了范围。功能。这是未定义的行为。您需要在堆上分配***ptrmalloc

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

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