web-dev-qa-db-fra.com

Comment copier les valeurs d'un tableau dans un nouveau?

J'essaie de comprendre cela par intermittence depuis une semaine et je continue à avoir des problèmes.

Mon objectif:

Ecrivez une fonction qui alloue de la mémoire pour un tableau de nombres entiers. La fonction prend en argument un pointeur entier, la taille du tableau et newSize à allouer. La fonction renvoie un pointeur sur la mémoire tampon allouée. Lorsque la fonction est appelée pour la première fois, la taille sera zéro et un nouveau tableau sera créé. Si la fonction est appelée lorsque la taille du tableau est supérieure à zéro, un nouveau tableau sera créé et le contenu de l'ancien tableau sera copié dans le nouveau tableau. Votre instructeur a fourni arrayBuilder.cpp en tant que code de démarrage pour ce défi de programmation. En outre, Lab9_1.exe est l'exécutable de cette application que vous pouvez tester.

Le code:

#include <iostream>
using namespace std;

int * arrayBuilder(int * arr, int size, int newSize);
void showArray(int * arr, int size);

int main()
{
int * theArray = 0;
int i;

cout << "This program demonstrates an array builder function." << endl << endl;

// create the initial array.  The initial size is zero and the requested size is 5.
theArray = arrayBuilder(theArray, 0, 5);

// show the array before values are added
cout << "theArray after first call to builder: " << endl;
showArray(theArray, 5);

// add some values to the array
for(int i = 0; i < 5; i++)
{
    theArray[i] = i + 100;
}

// show the array with added values
cout << endl << "Some values stored in the array: " << endl;
showArray(theArray, 5);

// expand the size of the array.  size is not the original size.  newSize
// must be greater than size.
theArray = arrayBuilder(theArray, 5, 10);

// show the new array with the new size
cout << endl << "The new array: " << endl;
showArray(theArray, 10);

cout << endl;

delete [] theArray; // be sure to do this a1t the end of your program!

system("pause");

return 0;
}

/*
FUNCTION: arrayBuilder
INPUTS Pointer to an array.  Size of the array. If size is zero, arr can be    NULL.
      Size of the new array.
OUTPUTS:  Returns a pointer to allocated memory.  If newSize is greater than size,
      an array of newSize is allocated and the old array is copied into the new
      array. Memory pointed to by the old array is deleted.  All new elements
      are initialized to zero.
*/


int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here


return NULL; // default return value.  No memory allocated!
}

/*
FUNCTION: showArray
INPUTS: Pointer to an array.  Size of the array. If size is zero, arr can be  NULL.
OUTPUTS:  Prints the contents of the array to the console.
*/


void showArray(int * arr, int size)
{
cout << "arr = ";

for(int i = 0; i < size; i++)
{
    cout << arr[i] << "  ";
}

cout << endl;

}

Mes difficultés: je ne sais pas comment changer les valeurs de "arr" et d'un tableau temporaire.

int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
    int * temp = new int [newSize];

for (int i = size; i < newSize; i++)
{
        *arr = *temp;
        temp++;
}

return NULL; // default return value.  No memory allocated!
}

une autre tentative en cherchant des réponses:

int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
int * temp = new int [newSize];
memcpy (temp, arr, size *sizeof(int));
// HINT: Design the function before writing it.
delete[]  arr;

for (int i = size; i < newSize; i++)
{
    temp[i] = i;
}

return NULL; // default return value.  No memory allocated!
}

Fondamentalement, mon objectif est que la réponse ressemble à ceci:

This program demonstrates an array builder function.

theArray after first call to the builder:
arr = 0 0 0 0 0

some values stored in the array:
arr = 100 101 102 103 104

the new array:
arr = 100 101 102 103 104 0 0 0 0 0

LE PROGRÈS!! Son ne s'écrase plus :-) C'est ici que je suis:

This program demonstrates an array builder function.

theArray after first call to builder:
arr = -842150451  0  0  0  0

Some values stored in the array:
arr = 100  101  102  103  104

The new array:
arr = -842150451  -842150451  -842150451  -842150451  -842150451  -842150451  -8
42150451  -842150451  -842150451  -842150451

Press any key to continue . . .

Je continuerai de bricoler et que tout le monde sache si je me heurte à un mur! Merci encore les gars!

D'ACCORD! enfin réussi à l'afficher correctement:

This program demonstrates an array builder function.

theArray after first call to the builder:
arr = 0 0 0 0 0

some values stored in the array:
arr = 100 101 102 103 104

the new array:
arr = 100 101 102 103 104 0 0 0 0 0

C'est ce que j'ai fait. Je sens que j'ai peut-être triché dans la deuxième partie quand je mets 0 valeurs pour "temp". Je croyais comprendre que j'allais prendre les données du tableau précédent et les insérer dans le nouveau, mais que je les refais simplement. (Donc, cela ne fonctionnera qu'avec cet ensemble particulier de valeurs [uniquement les 0]). Y a-t-il une manière différente de coder la deuxième partie pour qu'elle fonctionne universellement, quelles que soient les valeurs qui lui sont attribuées ???

int * arrayBuilder(int * arr, int size, int newSize)
{
int i = size;
int * temp = new int [newSize];
// What if the size is 0?
if (size <= 0)
{
    while (i < newSize)
    {
        temp[i] = 0;
        i++;
    }
}
// Assuming the size _isn't_ 0
else 
{
// "a new array will be created"  (good)

for (i = 0; i < newSize; i++)
{
    // The contents of the "old" array (arr) will be
    // copied into the "new" array (temp)
    while (i < size)
    {
        temp[i] = arr[i];
        i++;
    }
    while (i >= size && i < newSize)
    {
        temp[i] = 0;
        i++;
    }
    // as a hint, you can address the elements in 
    // both arrays using the [] operator:
    // arr[i]
    // temp[i]

}
}

// "The function returns a pointer to the allocated buffer."
// So, NULL is wrong, what buffer did you allocate?
return temp; // default return value.  No memory allocated!
}
4
Peter

Depuis que tu as fait des efforts.

Ecrivez une fonction qui alloue de la mémoire pour un tableau de nombres entiers.

Le prototype de cette fonction vous a été fourni:

int * arrayBuilder(int * arr, int size, int newSize);

La fonction prend en argument un pointeur entier, la taille du tableau Et newSize à allouer. La fonction renvoie un pointeur sur Le tampon alloué.

Cela ne dit rien de faire quoi que ce soit avec le "vieux" tableau (passé), nous devrions donc supposer qu'il doit être laissé seul.

Lorsque la fonction est appelée pour la première fois, la taille sera zéro et un nouveau tableau Sera créé.

Le texte ci-dessus n'a pas de sens compte tenu du contexte. N'hésitez pas à dire à votre instructeur que je l'ai dit. Si la taille est zéro, comment savoir combien d'éléments doivent être alloués?

Si la fonction est appelée lorsque la taille du tableau est supérieure à zéro, un nouveau tableau Sera créé et le contenu de l'ancien tableau sera Copié dans le nouveau tableau.

OK, maintenant le courage de ce qui doit être fait (tu donc ferme)

int * arrayBuilder(int * arr, int size, int newSize)
{
    // What if the size is 0?

    // Assuming the size _isn't_ 0
    // "a new array will be created"  (good)
    int * temp = new int [newSize];

    for (int i = size; i < newSize; i++)
    {
        // The contents of the "old" array (arr) will be
        // copied into the "new" array (temp)

        // as a hint, you can address the elements in 
        // both arrays using the [] operator:
        // arr[i]
        // temp[i]

        // something is wrong here...
        *arr = *temp;

        // you definitely _don't_ want to do this
        temp++;
    }

    // "The function returns a pointer to the allocated buffer."
    // So, NULL is wrong, what buffer did you allocate?
    return NULL; // default return value.  No memory allocated!
}
5
Chad

Vous avez déjà la réponse ici:

memcpy (temp, arr, size *sizeof(int));

mais vous faites plusieurs autres erreurs par la suite. Avant tout, vous devez return temp ; pas return NULL ;

Mais vous n’avez pas non plus besoin de la boucle après le delete arr[] ;

Ne pas également delete arr[] si la taille est zéro.

5
woolstar

Juste pour vous aider à comprendre pourquoi la première tentative n'a pas fonctionné:

*arr = *temp;

Ceci attribue une valeur à l'ancien tableau, à partir du nouveau tableau. C'est à l'envers.

Mais cela ne fait que cibler la première valeur, *arr ne change pas. Vous incrémentez *temp, mais vous devez également incrémenter *arr. (En outre, la manipulation manuelle du pointeur comme celle horrible et memcopy () est bien meilleure. Mais bon, c'est à des fins d'apprentissage, non?)

Aussi, pensez à cette boucle:

for (int i = size; i < newSize; i++)

C'est itératif une fois pour chaque bit que newSize est plus grand que la taille. Mais vous faites deux choses ici. 1) Copie des données et 2) Initialisation des nouvelles données. Cette boucle for est bonne pour parcourir les nouvelles données, mais ce n'est pas la boucle que vous voulez pour copier les données que vous avez déjà. Cela irait de zéro à la taille, non? 

Et lorsque vous avez terminé, vous devez renvoyer l'adresse du tableau que vous avez construit.

return NULL; // default return value.  No memory allocated!

C'est juste un code factice factice. C'est un espace réservé par l'enseignant. Cela fait partie du code que vous êtes censé changer.

Selon votre mise à jour:

Je sens que j'ai peut-être triché dans la deuxième partie quand je mets 0 valeurs pour "temp"

Eh bien quoi d'autre alliez-vous mettre là-bas? Vous copiez sur les anciennes données du tableau. Ensuite, vous développez le tableau. Qu'est-ce qui se passe dans le nouveau territoire? Zéro valeur par défaut est parfaitement valide. 

Y a-t-il une manière différente de coder la deuxième partie pour qu'elle fonctionne universellement, quelles que soient les valeurs qui lui sont attribuées ???

Eh bien oui, mais vous devriez vraiment avoir quelque chose à dire. Votre fonction ArrayBuilder peut accepter des arguments supplémentaires, éventuellement en tant que fonction variadique , afin de savoir quelles valeurs mettre dans les nouveaux champs. Mais votre déclaration de fonction n'a pas cela. Tout ce que cela fait, c'est d'agrandir le tableau. 

De plus, dans votre dernière édition, vous avez ces deux boucles while qui parcourent i à l’intérieur d’une boucle for qui itère également à travers i. Cela fonctionnera, mais juste pour que vous sachiez que c'est un peu ... grossier. C'est le genre de chose qui va vous causer des ennuis quand les choses deviennent plus compliquées.

Vous pouvez le faire à la place:

for (i = 0; i < newSize; i++)
{
  if(i < size)
  {
    temp[i] = arr[i];
  }
  else // if(i >= size && i < newSize) //Wait a sec, this "if" is superfluous. It's conditions are enforced the the first if and the loop condition.
  {
    temp[i] = 0;
  }
}

Vous devriez également probablement supprimer les commentaires qui donnent l'impression que quelqu'un d'autre a écrit votre code pour vous. Parce que quelqu'un d'autre a fait vos devoirs pour vous. C'est mieux de 

Enfin, THAL SHALT INDENT THY CODE!

1
Philip

Si j’ai bien compris l’affectation, la fonction devrait ressembler à ceci: Je remplacerais tout d’abord la déclaration de fonction

int * arrayBuilder(int * arr, int size, int newSize);

for

int * arrayBuilder( const int *arr, size_t size, size_t newSize );

Voici sa définition

int * arrayBuilder( int * arr, int size, int newSize)
{
   int *tmp = 0;

   if ( newSize >= 0 )
   {
      tmp = new int[newSize] {};

      int copy_size = std::min( size, newSize );

      if ( copy_size > 0 ) std::copy( arr, arr + copy_size, tmp );
   }

   delete []arr;

   return tmp;
}
0
Vlad from Moscow

C'est un code horriblement complexe. La programmation est tout au sujet de réduction complexité.

Dans cet esprit, voici une solution C++ appropriée:

std::vector<int> arr = {1, 2, 3, 4, 5};
std::vector<int> copy = arr;

C'est tout. J'espère que cela illustre pourquoi devrait utiliser la bibliothèque standard (ou d'autres bibliothèques appropriées) plutôt que de réinventer la roue. D'après le code que vous avez publié, je suppose que vous avez appris (ou êtes en train d'apprendre) C++ à partir d'un livre ou d'un cours horrible. Débarrassez-vous de cela et obtenez un livre approprié . C++ est assez complexe tel quel, inutile d'ajouter une complexité inutile.

0
Konrad Rudolph

Essaye ça:

Code:

#include <iostream>

using namespace std;

int a[3] = 
{
    1,
    2,
    3
};

int b[3];

int main ()
{
    cout << endl;
    cout << "Array #1 elements: " << endl;
    for(int i = 0; i < 3; ++i)
    {
        cout << a[i] << " ";
    }

    for(int i = 0; i < 3; ++i)
    {
        b[i] = a[i];
    }
    cout << endl << endl;
    cout << "Copying Array #1 elements to Array #2..." << endl;
    cout << endl;
    cout << "Array #2 elements: " << endl;
    for(int i = 0; i < 3; ++i)
    {
        cout << b[i] << " ";
    }
    cout << endl << endl;
    return 0;
}
0