簡體   English   中英

C 指向指針並通過引用傳遞

[英]C Pointer to Pointer and Pass by Reference

我正在嘗試學習 C,我對指針的指針有點掛斷。 我想我理解你為什么需要它們,但不能完全理解正在發生的事情。

例如,下面的代碼似乎不像我期望的那樣工作:

#include <stdio.h>

int newp(char **p) {
  char d = 'b';
  *p = &d;
  /*printf("**p = %c\n", **p);*/
  return 1;
}

int main() {
  char c = 'a';
  char *p = &c;
  int result;

  result = newp(&p);
  printf("result = %d\n", result);
  printf("*p = %c\n", *p);
  printf("c = %c\n", c);

  return 0;
}

我得到的結果是這樣的:

result = 1
*p = 
c = a

*p 打印為空。 相反,我希望*p = b

但是,如果我取消注釋第 6 行( newp函數中的printf ),那么我會得到:

**p = b
result = 1
*p = b
c = a

我錯過了什么?

您正在處理未定義的行為。 變量d是本地的(駐留在堆棧上)並且在封閉的 function ( newp ) 返回后不可用。

當在newp之外取消引用p時,堆棧&d上的地址可能會被其他一些局部變量覆蓋,或者它可能包含垃圾。

您將局部變量 ( d ) 的地址存儲在*p中,然后在變量超出 scope 時取消引用它。 未定義的行為

您可能“缺少”關鍵字static ,如:

int newp(char **p) {
    static char d = 'b';   /* <--- HERE */
    *p = &d;
    /*printf("**p = %c\n", **p);*/
    return 1;
}

這個static關鍵字使編譯器將局部變量定位在“靜態存儲”中,該局部變量在調用newp()之后的時間段內繼續存在(即保持其值)。 但是,此 memory 只有一個副本 - 包含 function ( newp ) 的每個后續調用都重新使用相同的 memory 位置並可能覆蓋當時的值。

如果沒有static關鍵字來限定您的局部變量聲明,則存儲將是“自動”的,這意味着在包含 function 已返回后,它將自動從當前使用中解除。 newp返回后,以前用於局部變量的 memory 可以用於任何目的。

#include <stdio.h>

// Here *pointer means that the parameter that this function 
// will expect will be a pointer. 
void changeViaPointer(int *pointer);

// Pointer of a pointer.
void changeViaPointerInBetween(int **pointer);

int main(){

    int number;
    number = 20;

    // Here *pointer means that the variable that is declared will be a pointer.
    int *pointer;

    // Actually asigning value to the pointer variable.
    pointer = &number;

    // Pointer of a pointer.
    int **pointerInBetween;

    // Assigning value to the pointer of a pointer. 
    // Assigning the memory location where this pointer points to. 
    // So this is a pointer in between.
    pointerInBetween = &pointer;

    printf("The number before changing is %d\n", number);

    // Pass the pointer variable.
    changeViaPointer(pointer);
    printf("The number after pointer changing is %d\n", number);

    // Pass the pointer of a pointer variable.
    changeViaPointerInBetween(pointerInBetween);
    printf("The number after pointer in between changing is %d\n", number);

    return 0;
}

void changeViaPointer(int *pointer){

    // Okay, at this point we have received a variable called pointer,
    // which points to some value. In order to access this value
    // we need to use *pointer.
    // BUT THIS IS DIFFERENT FROM THE *pointer IN THE FUNCTION DECLARATION!!!
    *pointer = *pointer + 20;
}

void changeViaPointerInBetween(int **pointer){

    // **pointer explanation:
    // Only pointer is the memory location
    // *pointer  is the value of that memory location, which in this specific case is also a memory location
    // **pointer is the value of what the other pointer points to.
    **pointer = **pointer + 20;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM