2012-11-08 35 views
10

我是C++新手(每個新手XD的常用介紹)。那麼,我正在開發一個程序,當一個意外的行爲出現! 我追蹤了我的程序中的變量和數組,直到我成功地確定了執行此行爲的代碼模式!更改函數內數組元素的值

下面是我所使用的追蹤是如何工作的:

#include <iostream> 

using namespace std; 

void showArray(int arr[], int n) 
{ 
    for(int i = 0; i < n; i++) cout << arr[i] << " "; 
    cout << endl; 
} 
void someFunction(int x[], int n) // changes the original values 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} 
void someFunction2(int * x, int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} // changes the original values 
int someFunction3(int x[], int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // changes the original values 
int someFunction4(int x[], int n) 
{ 
    x = new int[n]; 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // does NOT change the original value 

int main(void) 
{ 
    int * y = new int[3]; 
    y[0] = 0; 
    y[1] = 1; 
    y[2] = 2; 
    showArray(y, 3); 
    someFunction4(y, 3); 
    showArray(y, 3); 
    return 0; 
} 

我覺得跟評論的代碼說明問題出在哪裏,但這裏更多的信息: 有4個功能,即someFunction ,一些功能2,一些功能3,一些功能4。 有一個數組y,它的值爲0,1,2。所有函數都會更改原始數組的值。也就是說,在someFunctionX調用之後,main函數中y的元素比調用函數之前發生的變化要多。

我的問題是:爲什麼someFunction4是唯一不改變值的函數?

在此先感謝。併爲我的壞英語感到抱歉。

回答

7

someFunction4中,您將x指定爲指向一個整數的new,然後將其分配。您傳入函數的變量所指向的數組仍然指向舊數組。舊陣列保持不變,因爲在someFunction4內,您已將x設置爲引用不同的陣列,即通過new在您的功能中創建的陣列。

爲了使原xsomeFunction4()抱着你分配的值,做兩件事情之一:

1)擺脫x = new int[n];。這將使someFunction4()像以前那樣工作。

2)將指針作爲someFunction4()的參數傳遞給x,並讓someFunction4()取指針。

int someFunction4(int *x[], int n) 
{ 
    *x = new int[n]; 
    (*x)[0] = 2; 
    (*x)[1] = 1; 
    (*x)[2] = 0; 
    return 0; 
} // Makes x point to a new a new array 

而在你的主,做

someFunction4(&y,3); 
+0

謝謝。你的回答很明確。那麼,如何讓舊數組獲得新的價值? – joker

+0

擺脫賦值'x = new int [n];' – GraphicsMuncher

+0

如果我想從函數內改變數組大小,該怎麼辦? – joker

0

你必須瞭解如何將參數傳遞給函數

當你調用SomeFunctionN(Y,3)然後裏面SomeFunctionN的 'X'變量是一個局部變量,被初始化爲指向y在main中指向的同一個數組。

然後在SomeFunc4中創建一個新數組並將您的本地指針(x)更改爲指向新數組。所有的更改也達到新的陣列

在所有其他情況下,你離開單獨X

2

我做了一個測試用例。

http://ideone.com/fyl6MX

結果

0 1 2 
0x943b008 
0x943b018 
0x943b008 
0 1 2 

第二個是地址是新表的地址。正如你可以看到你的指針在本地指向其他地址。

#include <iostream> 

using namespace std; 

void showArray(int arr[], int n) 
{ 
    for(int i = 0; i < n; i++) cout << arr[i] << " "; 
    cout << endl; 
} 
void someFunction(int x[], int n) // changes the original values 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} 
void someFunction2(int * x, int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} // changes the original values 
int someFunction3(int x[], int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // changes the original values 
int someFunction4(int x[], int n) 
{ 
    x = new int[n]; 
    std::cout << x << endl; 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // does NOT change the original value 

int main(void) 
{ 
    int * y = new int[3]; 
    y[0] = 0; 
    y[1] = 1; 
    y[2] = 2; 
    showArray(y, 3); 

    std::cout << y << endl; 

    someFunction4(y, 3) ; 
    std::cout << y << endl; 

    showArray(y, 3); 
    return 0; 
} 
+0

那麼如何從一個函數內改變原來的指向值呢? – joker

5

在每個someFunctionsomeFunction2someFunction3,你實際上是傳遞一個pointer到您main()您的陣列分配的內存。這意味着,當您對數據進行操作該指針指向:

x[1] = 1; 

它實際上影響了相同的內存y指向main()回來了!

然而,在someFunction4,你重新分配指針x指向新的內存聲明:

x = new int[n]; 

,使其不再指向相同的內存y確實在main(),任何變化在此之後(但僅在someFunction4範圍內!)不會影響y