[英]C - modify the address of a pointer passed to a function
我不明白為什么在function
外不保留對作為parameter
傳遞給function
的pointer
地址的修改(調用該函數后ptr
的地址不變):
void advance(int *ptr) {
ptr = ptr + 1
}
當我可以在同一函數內修改ptr
指向的value
: *ptr = *ptr + 1
。
PS:我知道使用pointer to a pointer
**ptr
pointer to a pointer
可以實現我想要的功能。
這是因為C語言中函數的參數始終按值傳遞。 您通過值傳遞的是一個地址。 修改ptr
您正在修改調用方值的副本 。
要修改呼叫者的值,您需要額外的間接級別:
void advance(int **ptr) {
*ptr = *ptr + 1;
}
因為C 不是按引用調用,所以即使引用/指針作為參數 ,它也始終是按值調用 。
它與其他語言不同,可以區分參數類型。
當您定義函數void advance(int * ptr)時,這意味着將在堆棧中創建一個指針,該指針指向與原始指針相同的地址。 要查看證明,請嘗試打印原始指針的地址(&orig)和參數指針的地址(&param),以及“指向”的地址(orig,param)。 指針地址將有所不同,但指向的地址將相同。
因此,我們有兩個指向同一區域的指針,如果您修改參數,它將指向新區域,但是orig值不會改變,它指向與以前相同的區域。
這就是為什么需要一個指向指針的原因。 如果使用指向指針的指針(int ** ppointer =&orig),則將有一個指針直接指向orig存儲“指向”地址的區域(orig當前指向的區域)。 通過更改* ppointer的值,您也將直接更改orig的值。
您實際上回答了自己的問題;)
作為參數傳遞給函數的指針地址的修改不會在該函數之外持久存在
在函數內部,您正在管理參數的副本。 您可以修改指向的值,因為您明確要求在特定地址進行更改。
void advance(int *ptr)
該函數調用將在稱為ptr的堆棧中創建一個新變量(在Advance函數的堆棧中),該變量是指向整數的指針,隨着該函數的增加,該函數僅在退出advace函數后才起作用高級功能,變量丟失。 高級功能的堆棧不再存在
****** /---\ * 20 * ----> | 2 | ****** \---/ i 20-24
在這里, i
是指向具有值2
的存儲位置20
的指針,即當將20 + sizeof(int) - 1
的二進制數據解釋為十進制數時。 現在,當您將i
傳遞給advance
,它具有一個參數ptr
,真正發生的是
****** /---\ ****** * 20 * ----> | 2 | <---- * 20 * ****** \---/ ****** i 20-24 ptr
ptr = i;
也就是說, i
的值設置為ptr
的值,因為i
和ptr
是指針,所以這里實際上是地址。
當您增加ptr
它只會使指針指向一個不同的地址,而不會對i
任何更改,因為ptr
是一個副本而不是i
本身。 但是,如果使用運算符*
更改ptr
處的值,即*ptr = 10
; 那么上面的2
將更改為10
從而也更改了*i
,它也指向20。再次注意, i
的地址或值未更改,只有它指向的位置發生了更改。 如果有10個指向地址20
指針,即使沒有指針被更改,但所有指向的值也都被更改。
見功能:
void demonstrate(int num) {
num = num + 1; // type of num is int
} // destroys "num", because num's scope is only "demonstrate" function
在您的職能:
void advance(int *ptr) {
ptr = ptr + 1; // type of ptr is int* and ptr is incremented
} // destroys "ptr" for the similar reason
但是,您需要一個修改地址的函數( IN 指針 )。 因此,完整的解決方案應該是:
#include <stdio.h>
void advance(int **ptr) { //ptr is a pointer to a pointer
// so *ptr is the pointer that is pointed by ptr
*ptr = *ptr + 1; // incrementing the address IN the pointer pointed by ptr
} // destroys "ptr" for the reason above
int main() {
int x = 5;
// initially assign "ptrToChange"
int *ptrToChange = &x;
// "ptrToChange" now points to x
// passing address OF "ptrToChange" to "advance" function
advance(&ptrToChange);
// now "ptrToChange" does NOT point to x
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.