簡體   English   中英

將指針地址與指針傳遞給C中的指針

[英]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.

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