2012-11-08 13 views
10

Jestem nowy w C++ (zwykle intro dla każdego początkującego XD). Cóż, rozwijałem program, kiedy pojawiło się nieoczekiwane zachowanie !! Śledziłem zmienne i tablice w moim programie, aż udało mi się określić wzór kodu, który wykonuje to zachowanie !!zmieniając wartości elementów tablicy z funkcji

Oto, co Użyłem prześledzić, jak to wszystko działa:

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

Myślę, że kod z uwagami wyjaśnia, gdzie jest problem, ale tutaj jest więcej informacji: istnieją 4 funkcje, mianowicie someFunction , someFunction2, someFunction3, someFunction4. Istnieje tablica, y, która ma wartości 0, 1, 2. wszystkie funkcje zmieniają wartość oryginalnej tablicy. Oznacza to, że elementy y w głównej funkcji po wywołaniu someFunctionX zmieniają się, niż przed wywoływaniem funkcji.

moje pytanie brzmi: dlaczego someFunction4 jest jedyną funkcją, która nie zmienia wartości?

z góry dzięki. i przepraszam za mój zły angielski.

Odpowiedz

7

W someFunction4, przypisać x wskazywać na new tablicy liczb całkowitych, które następnie przypisać. Tablica wskazywana przez zmienną, którą przekazałeś do funkcji, nadal wskazuje na starą tablicę. Stara tablica pozostaje niezmieniona, ponieważ w someFunction4 ustawiono x, aby odwoływać się do innej tablicy, a mianowicie tej utworzonej w funkcji przez new.

Aby oryginalny x w someFunction4() trzymać wartości przypisane, zrobić jedną z dwóch rzeczy:

1) Pozbyć x = new int[n];. To sprawi, że someFunction4() będzie działało jak poprzednie.

2) Przekaż wskaźnik do x jako argument do someFunction4() i zmień wskaźnik na 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 

A w głównym wykonaj

someFunction4(&y,3); 
+0

dzięki. Twoja odpowiedź jest jasna. Jak sprawić, by stara tablica miała nową wartość? – joker

+0

Pozbądź się przypisania 'x = new int [n];' – GraphicsMuncher

+0

co jeśli chcę zmienić rozmiar tablicy z wewnątrz funkcji? – joker

0

Musisz zrozumieć, w jaki sposób argumenty są przekazywane do funkcji

Po wywołaniu SomeFunctionN (y, 3), a następnie wewnątrz SomeFunctionN 'x' zmienna jest lokalną zmienną zainicjowaną do punktu w tej samej tablicy, na której wskazywałeś w głównej.

w SomeFunc4 utworzysz nową tablicę i zmienisz lokalny wskaźnik (x) na punkt w nowej tablicy. Wszystkie zmiany uderzyć nową tablicę

We wszystkich innych przypadkach pozostawić X sam

2

Zrobiłem testcase.

http://ideone.com/fyl6MX

wynik

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

drugi jest adres to adres nowej tabeli.Jak widać twój wskaźnik wskazuje lokalnie na inny adres.

#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

, jak zmienić oryginalną wartość wskazującą z funkcji? – joker

5

W każdym z someFunction, someFunction2 i someFunction3, są faktycznie przechodzącą pointer pamięci masz przydzielonego dla tablicy w main(). Oznacza to, że podczas pracy na danych to punkty wskaźnik do:

x[1] = 1; 

To faktycznie wpływa na samo wspomnienie, że y punkty do tyłu w main()!

Jednak w someFunction4, ty przypisanie wskaźnik x pkt do nowej pamięci ze stwierdzeniem:

x = new int[n]; 

Więc to już punktów do tej samej pamięci y robi w main(), a wszelkie zmiany potem to zrobisz (ale tylko w zakresie someFunction4!) nie wpłynie to na y.

Powiązane problemy