web-dev-qa-db-fra.com

modifier les valeurs des éléments d'un tableau depuis une fonction

Je suis nouveau en C++ (l'intro habituelle pour chaque débutant XD). Eh bien, je développais un programme quand un comportement inattendu est apparu !! J'ai tracé les variables et les tableaux de mon programme jusqu'à ce que je sois parvenu à déterminer le modèle de code qui exécute ce comportement !!

Voici ce que j'ai utilisé pour tracer comment les choses fonctionnent:

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

Je pense que le code avec les commentaires explique où se situe le problème, mais voici plus d'informations: Il y a 4 fonctions, à savoir someFunction, someFunction2, someFunction3, someFunction4 . , 1, 2 . Toutes les fonctions modifient la valeur du tableau d'origine. C'est-à-dire que les éléments de y dans la fonction principale après le changement d'appel someFunctionX par rapport à ce qu'ils étaient avant d'appeler la fonction.

ma question est: pourquoi someFunction4 est la seule fonction qui ne change pas les valeurs?

merci d'avance. et désolé pour mon mauvais anglais.

11
joker

Dans someFunction4, vous affectez x pour qu'il pointe vers un tableau d'entiers new que vous affectez ensuite. Le tableau pointé par la variable que vous avez transmise à la fonction pointe toujours sur l'ancien tableau. L'ancien tableau reste inchangé, car dans someFunction4 vous avez défini x pour référencer un autre tableau, à savoir celui que vous avez créé dans votre fonction via new.

Pour que la variable x in someFunction4() d'origine contienne les valeurs que vous avez affectées, effectuez l'une des opérations suivantes:

1) Débarrassez-vous de x = new int[n];. Cela fera fonctionner someFunction4() comme les précédents.

2) Passez un pointeur sur x comme argument de someFunction4() et demandez à someFunction4() de prendre un pointeur.

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

Et dans votre main, faites

someFunction4(&y,3); 
7
GraphicsMuncher

Dans chacune des variables someFunction, someFunction2 et someFunction3, vous transmettez en réalité un pointeur à la mémoire que vous avez allouée pour votre tableau dans main(). Cela signifie que lorsque vous utilisez les données, ce pointeur pointe vers:

x[1] = 1;

En fait, cela affecte la même mémoire que y pointe vers main()!

Cependant, dans someFunction4, vous réaffectez le pointeur x pour qu'il pointe vers une nouvelle mémoire avec l'instruction:

x = new int[n];

Ainsi, il ne pointe plus vers la même mémoire que y dans main(), et toute modification que vous y apporterez par la suite (mais uniquement dans le cadre de someFunction4!) N'aura aucune incidence sur y.

5
kevintodisco

J'ai fait un test. 

http://ideone.com/fyl6MX

résultat 

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

La deuxième est l'adresse est une adresse de la nouvelle table. Comme vous pouvez le voir, votre pointeur pointe localement sur une autre adresse. 

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

Vous devez comprendre comment les arguments sont passés aux fonctions

Lorsque vous appelez SomeFunctionN (y, 3), à l'intérieur de SomeFunctionN, la variable 'x' est une variable locale initialisée pour pointer vers le même tableau que celui que y désignait dans main.

dans SomeFunc4, vous créez ensuite un nouveau tableau et modifiez le pointeur local (x) pour qu'il pointe vers le nouveau tableau. Toutes les modifications que vous apportez atteignent le nouveau tableau

Dans tous les autres cas, vous laissez x seul

0
pm100