[英]passing a pointer address vs pointer to a pointer in C
我對這兩段代碼有些困惑:
版本1 :(在編譯后發出警告)
int func(int *ptr2)
{
*ptr2 += 1;
}
int main()
{
int a = 5;
int *ptr = &a;
printf("Address of a: %x\n", a);
printf("Before: %x\n", ptr);
func(&ptr);
printf("After: %x\n", ptr);
return 0;
}
輸出:
Address of a: 5770a18c
Before: 5770a18c
After: 5770a18d
版本2:
int func(int **ptr2)
{
*ptr2 += 1;
}
int main()
{
int a = 5;
int *ptr = &a;
printf("address of a: %x\n", &a);
printf("Before: %x\n", ptr);
func(&ptr);
printf("After: %x\n", ptr);
return 0;
}
輸出:
Address of a: cc29385c
Before: cc29385c
After: cc293860
如果在通過引用傳遞時我正確地理解了C中的指針,那么我們正在創建指向該位置的指針。 這使我們可以通過取消引用運算符來更改指針所持有的地址處的值。
但是,如果要更改指針持有的值,可以使用指向指針的指針。 我們傳遞指針的地址並創建一個新的指針來保存該地址。 如果要更改該值,則可以使用解引用運算符訪問指針(在其他位置定義)的值。
希望我走在正確的軌道上,但我一直在努力可視化版本1的具體情況。 主要是,我只想了解這兩個程序之間在化妝和輸出方面的區別。 我認為版本1仍然是指向指針的指針,但是為什么兩個程序之間的增量值不同? 如果版本1成功增加了ptr的值(我懷疑不是),為什么我找不到具有相同語法的代碼? 我想我在這里錯過了一些瑣碎的事情...任何幫助,我們感激不盡
根據您的輸出,您似乎正在為32位系統進行編譯,其中地址和int
都具有該大小。
當您將*ptr
的值遞增為int
,它將簡單地加1。
當*ptr
解析為int*
,它將以sizeof(int)
遞增,因為在這種情況下當前地址的值是4個字節長,因此我們必須將地址增加一個int
消耗的字節數,以便我們指的是下一個int。 請注意,僅當您實際上已在后續地址中分配了內存時,此操作才有效。
通常,當被調用方需要修改指向的地址時,您會傳遞一個T**
-例如,被調用方執行malloc()
來為指針分配空間。
&ptr
是指向指針的指針,但是傳遞給func()
是指向以實現定義的方式從&ptr
轉換為int
的指針。 然后, *ptr2 += 1;
是遞增int
並將1加到ptr2
指向的對象( main()
的指針ptr
,它最終與系統中的`int一樣具有重新表示形式)。
在版本2中,指向指針的指針已正確傳遞給func()
。 因此,執行指針算術運算,並將int
的大小添加到地址中。
請注意,您通過將類型錯誤的數據傳遞給printf()
來調用未定義的行為 。 打印指針的正確方法是這樣的:
printf("Before: %p\n", (void*)ptr);
如您所見,將指針強制轉換為void*
並使用%p
說明符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.