web-dev-qa-db-fra.com

Comparaison de tableaux pour l'égalité en C ++

Quelqu'un peut-il m'expliquer s'il vous plaît pourquoi la sortie du code suivant indique que les tableaux sont pas égaux?

int main()
{

    int iar1[] = {1,2,3,4,5};
    int iar2[] = {1,2,3,4,5};

    if (iar1 == iar2)
        cout << "Arrays are equal.";
    else
        cout << "Arrays are not equal.";

    return 0;   
}
41
vladinkoc
if (iar1 == iar2)

Ici iar1 et iar2 sont en décomposition en pointeurs sur les premiers éléments des tableaux respectifs. S'agissant de deux tableaux distincts, les valeurs de pointeur sont bien sûr différentes et vos tests de comparaison ne sont pas égaux.

Pour faire une comparaison élément par élément, vous devez soit écrire une boucle; Ou utiliser std::array à la place

std::array<int, 5> iar1 {1,2,3,4,5};
std::array<int, 5> iar2 {1,2,3,4,5};

if( iar1 == iar2 ) {
  // arrays contents are the same

} else {
  // not the same

}
60
Praetorian

Comme personne n'en a encore parlé, vous pouvez comparer des tableaux avec le std::equal algorithme:

int iar1[] = {1,2,3,4,5};
int iar2[] = {1,2,3,4,5};

if (std::equal(std::begin(iar1), std::end(iar1), std::begin(iar2)))
    cout << "Arrays are equal.";
else
    cout << "Arrays are not equal.";

Vous devez inclure <algorithm> et <iterator>. Si vous n'utilisez pas encore C++ 11, vous pouvez écrire:

if (std::equal(iar1, iar1 + sizeof iar1 / sizeof *iar1, iar2))

Vous ne comparez pas le contenu des tableaux, vous comparez les adresses des tableaux. Puisqu'ils sont deux tableaux distincts, ils ont des adresses différentes.

Évitez ce problème en utilisant des conteneurs de niveau supérieur, tels que std::vector, std::deque, ou std::array.

14
Fred Larson

Le tableau n'est pas un type primitif et les tableaux appartiennent à différents adresses dans la mémoire C++.

6
Paul S.

Vous comparez les adresses au lieu des valeurs.

1
Rahul Tripathi

Si vous êtes réticent à changer votre code existant en std::array, Utilisez plutôt deux méthodes qui prennent arguments de modèle non typés :

//Passed arrays store different data types
template <typename T, typename U, int size1, int size2>
bool equal(T (&arr1)[size1], U (&arr2)[size2] ){
    return false;
}

//Passed arrays store SAME data types
template <typename T, int size1, int size2>
bool equal(T (&arr1)[size1], T (&arr2)[size2] ){
    if(size1 == size2) {
        for(int i = 0 ; i < size1; ++i){
            if(arr1[i] != arr2[i]) return false;
        }
        return true;
    }
    return false;
}

Voici le démo . Notez que, lors de l'appel, nous devons simplement transmettre les variables de tableau, par exemple. equal(iar1, iar2) dans votre cas, inutile de passer à la taille des tableaux.

1
Saurav Sahu

Personne ne mentionne memcmp? C'est aussi un bon choix.

/* memcmp example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char buffer1[] = "DWgaOtP12df0";
  char buffer2[] = "DWGAOTP12DF0";

  int n;

  n=memcmp ( buffer1, buffer2, sizeof(buffer1) );

  if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
  else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
  else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);

  return 0;
}

Réf.: http://www.cplusplus.com/reference/cstring/memcmp/

0
Xiangyi Meng

Droite. Dans most, si ce n’est toutes les implémentations de C, l’identificateur de tableau peut être converti implicitement en un pointeur sur le premier élément (c’est-à-dire l’adresse du premier élément). Ce que vous faites ici, c'est comparer ces adresses, ce qui est évidemment faux.

Au lieu de cela, vous devez parcourir les deux tableaux, en comparant chaque élément les uns par rapport aux autres. Si vous arrivez à la fin des deux sans échec, ils sont égaux.

0
slugonamission

Lorsque nous utilisons un tableau, nous utilisons réellement un pointeur sur le premier élément du tableau. Par conséquent, cette condition if( iar1 == iar2 ) compare en réalité deux adresses. Ces pointeurs n'abordent pas le même objet.

0
vladinkoc