考慮下面的代碼(基本的C++):更改指針爲int傳遞給函數
#include <cstdio>
void changeNum(int* n) {
int x = 6;
n = &x;
}
int main() {
int num = 5;
changeNum(&num);
printf("num = %d\n", num);
}
爲什麼num
仍然是5?不應該n = &x
使它成爲6?
退出該功能後x
會被刪除嗎?
考慮下面的代碼(基本的C++):更改指針爲int傳遞給函數
#include <cstdio>
void changeNum(int* n) {
int x = 6;
n = &x;
}
int main() {
int num = 5;
changeNum(&num);
printf("num = %d\n", num);
}
爲什麼num
仍然是5?不應該n = &x
使它成爲6?
退出該功能後x
會被刪除嗎?
是否X退出該功能後會被刪除嗎?
是的。 x
是局部變量。那些在函數或塊中聲明的變量是局部變量。它們只能用於該函數或代碼塊內部的語句。
總之,這意味着當函數changeNum
結束時,變量x
(在堆棧上分配)將被銷燬。
爲什麼num仍然是5?不應該n = & x使它成爲6?
讓我們來分析你的奇怪功能:
void changeNum(int* n) {
int x = 6;
n = &x;
}
你在做什麼這裏是創建一個指針n
並分配給它的局部變量x
的地址。
各種評論都是錯誤的,注意!這不是未定義的行爲。指針n
被創建(因爲按值傳遞,注意指針本身是按值傳遞的!)當函數被調用並且函數結束時它被銷燬。
實際上,你的函數什麼都不做:創建一個指針,它由調用者提供的地址初始化,併爲它分配另一個地址。
changeNum(&num);
只是說:「創建一個臨時的指針,按值傳遞給函數changeNum
(按價值計算記妙傳指針!)」。所以它會創建指針的一個副本並被函數使用。
我建議你更好地學習,因爲你的代碼顯示你對指針的經驗不足。
但無論如何,正確的行爲應該是:
void changeNum(int* n) {
*n = 6
}
哪個分配6
到整數由n
指出!
非常好,想通了。謝謝! – galah92
不,它沒有像你期望的那樣工作。
&
運算符取得變量的地址。所以你正在分配地址,而不是數值。結果,你重載了指針,這是一個局部變量,它恰好具有引用另一個對象的語義。
有解決這個的2種方式:
方法1 取消引用N,這樣你就可以分配給它。
*n = x;
方法2 重寫方法接受一個參考,因爲它使分配更加直觀。
void changeNum(int &n) {
int x = 6;
n = x;
}
int main() {
int n = 5;
changeNum(n);
}
'int&n'會更好,但是,否則,很好的答案 –
@LightnessRacesinOrbit:我不關心格式化,工具應該爲我做這件事。我只是習慣於在'*'的同一位置放置'&',它恰好位於右側用於標識'int * a,b;'問題 – JVApen
這又一次!爲什麼你認爲一個邊緣案例很重要?有很多更重要的理由來決定一個路線,而國際海事組織他們都指向左對齊。右對齊'*'和'&'對於語言新手來說是非常混亂的,並且會導致很多SO的問題!好的代碼不會在一行上聲明多個變量。另外,你選擇右對齊'&'的原因不是因爲你右對齊'*';這是因爲<相同的原因,你右對齊'*'>所有相同的規則直接適用。 –
首先,變量「X」被聲明內部void ChangeNum(*n)
,而當它超出範圍時(當執行已離開函數)中,x被刪除。
其次,爲x爲num的值,修改void ChangeNum
看起來像這樣:
void changeNum(int &n)
{
int x = 6;
n = x;
}
,並調用像這樣的功能:
changeNum(num);
1.您僅更改了指針的副本(以引用形式通過該指針)。 2.如果這樣工作,你基本上會有未定義的行爲,因爲指針在函數調用返回時無效。 –
當退出函數時,'x'被刪除,所以在函數外使用它的地址是未定義的行爲。 – SurvivalMachine
瞭解取消引用操作符'*'。 –