2010-10-16 125 views
2

我一直在試圖在被調用的函數中創建一個指針變量,並以某種方式將它指向的值傳遞給主函數。我寫了幾個示例程序,但它似乎仍然錯過了一些東西。而挑戰在於使用指向指針的指針來實現這一點。這是我編寫和測試的代碼。我想我錯過了一些明顯的東西,你們可以指點一下嗎?謝謝。功能和指針指針

 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。

我也嘗試過全局聲明,但是din工作也是。我想維護本地聲明,看看它是否可能...

回答

4

我想你誤解了指針。你的代碼的問題是,你沒有意識到指針也是「按值傳遞」,函數中的指針是堆棧中的另一個變量,而不是你在主函數中聲明的那個。

我會用一個更簡單的例子,但這個想法是一樣的。

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)行中,計算機將主函數中的ptr值複製到堆棧上的新變量中,讓我們將其稱爲ptr'並將其傳遞給changePointerValue函數。

所以實際上,changePointerValue函數中的ptr是ptr',而不是您在主函數中聲明的那個。第二行changePointerValue,你給ptr'分配了一個新的內存地址,然後,ptr'被丟棄,因爲函數被返回。主函數中的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 
} 

編輯:

所以,如果你想在主函數打印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; 
    } 
+0

錯字:在你的例子中必須是「int * ptr =&x」(不是&a);) – zerm 2010-10-16 11:06:15

+0

感謝指針,我錯過了2個東西,一個是解引用和堆。 – Gan 2010-10-16 11:07:56

+0

@zerm:更正了,謝謝。 – 2010-10-16 11:08:06

1

你正在設置ptr該地址的地址的一個局部變量(b),其中在函數結束時超出範圍。這是未定義的行爲。您需要分配到***ptrmalloc堆上的東西。

此外,您將按值傳遞ptr到函數。因此,任何本地修改都不會反映在main中。你需要傳遞指針,即你需要一個int ****作爲參數。

我真的希望這不過是一次學習練習,因爲任何兩級以上的指針通常表示設計真的需要重新評估!

+0

我做這個mod在所調用的函數 「INT B = malloc的(的sizeof(int)的); B = 10;」 但結果仍然相同.... 這是你的意思還是我誤解你? – Gan 2010-10-16 10:37:21

+0

不,我的意思是像'p = malloc(sizeof(int)); pp =&b; ptr = &pp; * p = 10;'。 – 2010-10-16 10:41:04

+0

我通過從堆中取出一些內存來做了更改,但結果仍然相同。 *** ptr在被調用的函數中指向10,但是當控制權返回到主函數時,它指向32.在這種情況下,我沒有回答。它在我嘗試的簡單指針示例中工作。 – Gan 2010-10-16 10:52:26