[英]C passing pointer to a function confusion
我在這里有點困惑。 這來自一本很棒的 C 書,也許我質疑它太多,但不知何故它沒有意義。 我希望我能說出我的困惑。
假設下面&a
指向 memory 地址 87, &b
指向 memory 地址 120;
int a = 3;
int b = 4;
swap(&a, &b);
void swap(int *px, int *py) {
int temp;
temp = *px;
*px = *py;
*py = temp;
}
好的,問題來了:當我們調用 function 交換並將參數傳遞給 function時,我們實際上是將“px”設置為 87 還是將“*px”設置為 87?
因為如果我們將 *px 設置為 87,那么根據*
符號的定義,我們設置的是指針所指的值,而不是 memory 地址 p 持有的值,這在本例中是錯誤的。 另一方面,如果我們實際上將“p”設置為 87,那么 swap 中的代碼是有意義的,因為當我們在 function 中使用 * 符號時,我們將引用該地址中的值“3”這里。 但是為什么語法令人困惑,看起來好像我們正在設置
*px = 87
?
如果a
在地址 88(需要正確對齊)並且b
在地址 120,則:
// a | b | px | py | temp
int a=3; // 3 -- -- -- --
int b=4; // 3 4 -- -- --
swap(&a, &b); // 4 3 -- -- --
void swap(int *px, int *py)
{ // 3 4 88 120 --
int temp;
temp = *px; // 3 4 88 120 3
*px = *py; // 4 4 88 120 3
*py = temp; // 4 3 88 120 3
}
px
是&a
,它是88
,永遠不會改變。 *px
指(別名) a
。 它可能會被重新綁定到別名不同的變量,但這段代碼並沒有這樣做。
參數是px
並且類型為int*
。 該參數不是*px
。 出於這個原因,許多程序員將其寫為int* px
而不是int *px
。 調用swap(&a, &b)
的效果是px = &a
而不是*px = &a
。
但請注意,C 沒有“方法”,只有“功能”。
考慮您的swap
簽名:
void swap(int *px, int *py);
這意味着 swap 需要兩個指向int
的指針。 換一種說法:它取memory中的兩個int
值地址。
現在,當調用你的swap
function 時
swap(&a, &b);
第一個參數將是a
的地址(它是一個int
),第二個參數將是b
的地址(它也是一個int
)。
在swap
中, px
將是a
的地址, py
將是b
的地址。 因此,取消引用px
和py
將在a
和b
的地址處產生值 - 這將是 3 和 4。
*
可能意味着三種不同的東西,具體取決於上下文:
a * b
中,它表示乘法。int *a
中,它的意思是“我們現在聲明一個變量或參數a
,其類型為int *
(指向int
的指針)。*a
中(假設*
左邊沒有數據類型,所以這是一個表達式而不是聲明),它的意思是“ a
是一個指針,我們要查看它指向的值(也稱為取消引用指針”。 所以你的方法的參數是a
,而不是*a
; 星號是參數類型的一部分, a
是您設置為 87 的值。將指針聲明編寫為int * a
或int* a
而不是int *a
可能有助於更清楚地區分聲明和取消引用。
void swap(int *px, int *py)
你讀到這個px
和py
指向int
。 C中的參數是按值傳遞的。 因此,當您傳遞兩個 memory 地址(即指針)進行swap
時,您將這些地址分配給px
和py
。
也許混淆是由於 C 中的*
重載所致。 在參數列表中*
表示參數是指向左側類型的指針。 在 function 的實現中, *
用於取消引用指針。
您沒有設置任何指針,您始終只設置pointee的值。 *px = *py
將a
設置為b
的值。
變量a
指向 memory 地址 87。 &a
是87。然后我們將px
設置為 87。當然,這些是地址而不是整數,但這與 CPU 上發生的情況非常接近(當然在 CPU 上沒有'不是任何a
, &a
或px
)。
我們實際上是將“px”設置為 87 還是將“*px”設置為 87?
是的,您將px設置為 87。您正在使指針指向相同的位置,同時更改它們指向的值。
“因為如果我們將 *px 設置為 87”...
不,你的假設是錯誤的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.