2012-11-08 41 views
10

Tôi mới sử dụng C++ (phần giới thiệu thông thường cho mỗi XD mới). Vâng, tôi đã phát triển một chương trình, khi một hành vi bất ngờ xuất hiện !! Tôi truy tìm các biến và mảng trong chương trình của mình cho đến khi tôi đã thành công trong việc xác định mẫu mã thực hiện hành vi này !!thay đổi giá trị của các phần tử mảng từ bên trong một hàm

Đây là điều mà chính tôi đã sử dụng để theo dõi cách làm việc:

#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; 
} 

Tôi nghĩ rằng mã với các ý kiến ​​giải thích nơi mà vấn đề là, nhưng đây là biết thêm: có 4 chức năng, cụ thể là, someFunction , someFunction2, someFunction3, someFunction4. có một mảng, y, có giá trị 0, 1, 2. tất cả các hàm thay đổi giá trị của mảng ban đầu. Nghĩa là, các phần tử của y trong hàm chính sau khi thay đổi cuộc gọi someFunctionX hơn là trước khi gọi hàm.

câu hỏi của tôi là: tại sao someFunction4 là hàm duy nhất không thay đổi giá trị?

cảm ơn trước. và xin lỗi vì tiếng anh xấu của tôi.

Trả lời

7

Trong someFunction4, bạn chỉ định x để trỏ đến mảng số nguyên new, sau đó bạn chỉ định. Mảng được trỏ đến bởi biến mà bạn truyền vào hàm vẫn trỏ tới mảng cũ. Mảng cũ vẫn không thay đổi, vì trong vòng someFunction4 bạn đã đặt x để tham chiếu một mảng khác, cụ thể là mảng bạn đã tạo trong hàm của mình qua new.

Để làm cho gốc x trong someFunction4() giữ các giá trị bạn đã gán, thực hiện một trong hai điều:

1) Loại bỏ các x = new int[n];. Điều này sẽ làm cho someFunction4() hoạt động giống như những cái trước đó.

2) Chuyển con trỏ đến x làm đối số cho someFunction4() và có someFunction4() lấy con trỏ.

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 

Và trong chính bạn, làm

someFunction4(&y,3); 
+0

cảm ơn. Câu trả lời của bạn là rõ ràng. Vì vậy, làm thế nào để làm cho mảng cũ có giá trị mới? – joker

+0

Loại bỏ nhiệm vụ 'x = new int [n];' – GraphicsMuncher

+0

nếu tôi muốn thay đổi kích thước mảng từ bên trong hàm? – joker

0

Bạn phải hiểu như thế nào đối số được truyền cho chức năng

Khi bạn gọi SomeFunctionN (y, 3) sau đó bên SomeFunctionN 'x' biến là một biến cục bộ được khởi tạo để trỏ vào cùng mảng mà y đang trỏ vào chính.

trong SomeFunc4 bạn sau đó tạo một mảng mới và thay đổi con trỏ cục bộ (x) trỏ vào mảng mới. Tất cả thay đổi bạn thực hiện đã đạt đến mảng mới

Trong tất cả các trường hợp khác, bạn để lại x một mình

2

Tôi đã tạo một testcase.

http://ideone.com/fyl6MX

kết quả

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

một thứ hai là địa chỉ là địa chỉ của bảng mới.Như bạn có thể thấy con trỏ trỏ cục bộ trỏ đến địa chỉ khác.

#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

vậy làm thế nào để thay đổi giá trị trỏ ban đầu từ bên trong một hàm? – joker

5

Trong mỗi someFunction, someFunction2, và someFunction3, bạn đang thực sự đi qua một pointer vào bộ nhớ bạn phân bổ cho mảng của bạn trong main(). Điều này có nghĩa rằng khi bạn hoạt động trên các dữ liệu này điểm con trỏ đến:

x[1] = 1; 

Nó thực sự ảnh hưởng đến bộ nhớ tương tự mà y điểm để sao lưu trong main()!

Tuy nhiên, trong someFunction4, bạn phân công lại con trỏ x để trỏ đến bộ nhớ mới với tuyên bố:

x = new int[n]; 

Vì vậy, nó không còn điểm vào bộ nhớ tương tự mà y làm trong main(), và bất kỳ thay đổi bạn làm cho nó sau đó (nhưng chỉ trong phạm vi someFunction4!) sẽ không ảnh hưởng đến y.

Các vấn đề liên quan