簡體   English   中英

試圖了解C ++中的指針

[英]Trying to understand pointers in C++

我正在嘗試使用Jesse Liberty的“ 24小時內自學C ++”自己學習C ++。 我寫了這個簡短的程序來找出C ++中的指針。

#include <iostream>

void hMany(int count); // hMany function prototype


void hMany(int count){

    do {
        std::cout << "Hello...\n";
        count--;

        }  while (count >0 );

};


int main (int argc, const char * argv[]) {


    int counter;
    int * pCounter = &counter;

    std::cout << "How many hellos? ";
    std::cin >> counter;

    hMany(*pCounter);

    std::cout << "counter is: " << counter << std::endl;
    std::cout << "*pCounter is: " << *pCounter << std::endl;

    return 0;
}

結果輸出為:

How many hellos? 2
Hello...
Hello...
counter is: 2
*pCounter is: 2

傳遞指針(* pCounter)與傳遞參數(counter)有什么好處?

任何幫助將不勝感激。 路易斯

更新:

好。 該程序正在運行,我現在完全了解C ++指針。 謝謝大家的答復。 嘗試了Chowlett的代碼后,我得到了2條警告(不是錯誤)。 一個是! 沒有函數hMany和* pCount--的原型! 表達式結果未使用。 我能夠自行糾正原型,但無法弄清楚* pCount--警告。

我向我的朋友托尼求助,這是他的答案。

括號使事情按正確的順序發生。

(*pCount)--

表示跟隨指針指向它所指向的整數,然后遞減該整數,這就是您要執行的操作。

*pCount--

最終做錯了事,編譯器將其視為

*(pCount—)

它說要先遞減指針,然后將其指向要更改的指針之前的“整數”(沒有這樣的事情,因為只有一個整數調用了此函數),然后跟隨此遞減的指針而不執行任何操作在該內存位置帶有整數。 這就是為什么編譯器抱怨表達式結果未使用的原因。 編譯器是正確的。 此代碼會錯誤地遞減指針,獲取錯誤的整數,並且不會在任何地方存儲該錯誤的整數。

對於那些對C ++陌生的人來說,這是正確的代碼。

包括

無效hMany(int * pCount); // hMany函數原型

void hMany(int * pCount){// * pCount接收計數地址

do {
    std::cout << "Hello...\n";


    // The parentheses make things happen in the correct order.
    // says to follow the pointer to the integer it points to, 
    // and then decrement the integer.

          (*pCount)--; 

}  while (*pCount >0 );

}

int main(int argc,const char * argv []){

int counter;
int * pCounter = &counter;

std::cout << "How many hellos? ";
std::cin >> counter;

hMany(pCounter); // passing the address of counter

std::cout << "counter is: " << counter << std::endl;
std::cout << "*pCounter is: " << *pCounter << std::endl;

return 0;

}

int counter;
int * pCounter = &counter;

...

hMany(*pCounter); // Pass by value

hMany(counter);   // Pass by value

傳遞點(* pCounter)與傳遞參數(counter)有什么好處?

在這種情況下,什么都沒有,僅是一個教育示例。 它顯示您可以取消引用指針並通過*獲得其值。

此外,這兩種情況都是按價值傳遞的。

在實踐中,除非有充分的理由,否則應避免默認使用指針。

使用*pCountercounter沒有什么區別。 在這兩種情況下,您都將傳遞變量counter 但是,如果您實際上傳遞了指針本身,則會得到不同的行為。

考慮稍微不同的程序:

#include <iostream>

void hMany(int* pCount); // hMany function prototype


void hMany(int* pCount){

    do {
        std::cout << "Hello...\n";
        --*pCount;

        }  while (*pCount >0 );

}


int main (int argc, const char * argv[]) {


    int counter;
    int * pCounter = &counter;

    std::cout << "How many hellos? ";
    std::cin >> counter;

    hMany(pCounter);

    std::cout << "counter is: " << counter << std::endl;
    std::cout << "*pCounter is: " << *pCounter << std::endl;

    return 0;
}

在這種情況下,您的輸出將是:

How many hellos? 2
Hello...
Hello...
counter is: 0
*pCounter is: 0

通過將指針傳遞到counter (字面上是counter內存中的地址),您可以允許函數通過其存儲位置來更改counter

傳遞點(* pCounter)與傳遞參數(counter)有什么好處?

沒有“好處” ,這就是您應該傳遞指針pCounter指向的值的方式。

hMany(*pCounter) ->取消引用pCounter以獲取值

不同之處在於變量的范圍。

如果傳遞變量,它將在函數的本地范圍內復制到堆棧中。 更改該值的操作將在本地復制中完成,如果是這種情況,則第一,如果傳遞了大變量,則使用空間;第二,您需要從函數中返回該值(因為一旦執行該操作,堆棧將被破壞背部)

您可以這樣想:

堆:

當前函數堆棧:

[    ]
[    ]
[    ]
[    ]

當您調用另一個1元素時

[    ]
[    ]
[    ]
[    ]
[newel]

當您離開該功能時,它將被刪除,因此再次像這樣

[    ]
[    ]
[    ]
[    ]

新元素的價值不再受信任。

但是,如果這是指針的副本,則不要更改指針副本的值,而是要更改指針所指向的位置的值,因此堆棧將像這樣

[    ]
[ actual_value]
[    ]
[ pointer_to_value]

比您調用該函數

[    ]
[ actual_value]
[    ]
[ pointer_to_value]
[ pointer_to_value_copy]

這將更改堆棧上的actual_value,並退出刪除pointer_to_value的副本

[    ]
[ actual_value**changed]
[    ]
[ pointer_to_value]

指針實際上包含具有該內存地址表示的值的類型信息的內存地址。 它可以用於在內存地址中傳遞實體,而無需再次實例化它來更改其值或類似的值。

但是在您的程序中,使用指針不會帶來任何好處,因為在您的情況下,一個c ++函數hMany在內部重新實例化了其參數中的值類型,在您的情況下為'int count'。

正如其他答案指出的那樣,您需要將count指針傳遞給該函數。 在那種情況下,C ++函數將在其參數中重新實例化值的類型,但是由於類型是指針,因此程序將在C ++函數內部具有正確的count內存地址,並且可以正確更改正確標識的值。

暫無
暫無

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

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