2016-08-20 31 views
-2

考慮下面的代碼(基本的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會被刪除嗎?

+0

1.您僅更改了指針的副本(以引用形式通過該指針)。 2.如果這樣工作,你基本上會有未定義的行爲,因爲指針在函數調用返回時無效。 –

+0

當退出函數時,'x'被刪除,所以在函數外使用它的地址是未定義的行爲。 – SurvivalMachine

+0

瞭解取消引用操作符'*'。 –

回答

3

是否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指出!

+0

非常好,想通了。謝謝! – galah92

1

不,它沒有像你期望的那樣工作。

&運算符取得變量的地址。所以你正在分配地址,而不是數值。結果,你重載了指針,這是一個局部變量,它恰好具有引用另一個對象的語義。

有解決這個的2種方式:

方法1 取消引用N,這樣你就可以分配給它。

*n = x; 

方法2 重寫方法接受一個參考,因爲它使分配更加直觀。

void changeNum(int &n) { 
    int x = 6; 
    n = x; 
} 
int main() { 
    int n = 5; 
    changeNum(n); 
} 
+0

'int&n'會更好,但是,否則,很好的答案 –

+0

@LightnessRacesinOrbit:我不關心格式化,工具應該爲我做這件事。我只是習慣於在'*'的同一位置放置'&',它恰好位於右側用於標識'int * a,b;'問題 – JVApen

+0

這又一次!爲什麼你認爲一個邊緣案例很重要?有很多更重要的理由來決定一個路線,而國際海事組織他們都指向左對齊。右對齊'*'和'&'對於語言新手來說是非常混亂的,並且會導致很多SO的問題!好的代碼不會在一行上聲明多個變量。另外,你選擇右對齊'&'的原因不是因爲你右對齊'*';這是因爲<相同的原因,你右對齊'*'>所有相同的規則直接適用。 –

0

首先,變量「X」被聲明內部void ChangeNum(*n),而當它超出範圍時(當執行已離開函數)中,x被刪除。

其次,爲x爲num的值,修改void ChangeNum看起來像這樣:

void changeNum(int &n) 
{ 
    int x = 6; 
    n = x; 
} 

,並調用像這樣的功能:

changeNum(num);