web-dev-qa-db-ja.com

C ++での配列の等価性の比較

次のコードの出力が配列が等しくないであると言っている理由を誰かが私に説明できますか?

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)

ここに iar1およびiar2は、それぞれの配列の最初の要素へのポインタへのdecayingです。これらは2つの別個の配列であるため、もちろんポインター値は異なり、比較テストは等しくありません。

要素ごとの比較を行うには、ループを作成する必要があります。または std::array 代わりに

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

まだ誰も言及していないので、配列をstd::equalアルゴリズムと比較できます:

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.";

<algorithm><iterator>を含める必要があります。 C++ 11をまだ使用していない場合は、次のように記述できます。

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

配列の内容を比較するのではなく、配列のアドレスを比較するのです。これらは2つの別個の配列であるため、アドレスが異なります。

std::vectorstd::dequestd::arrayなどの高レベルのコンテナを使用して、この問題を回避してください。

14
Fred Larson

配列はプリミティブ型ではなく、配列はC++メモリ内の異なるaddressesに属します。

6
Paul S.

値ではなくアドレスを比較しています。

1
Rahul Tripathi

既存のコードを_std::array_に変更したくない場合は、代わりに 非型テンプレート引数 を取るいくつかのメソッドを使用します。

_//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;
}
_

デモ です。呼び出し中に、配列変数を渡すだけでよいことに注意してください。 equal(iar1, iar2)あなたの場合、配列のサイズを渡す必要はありません。

1
Saurav Sahu

誰もmemcmpに言及していませんか?これも良い選択です。

/* 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;
}

参照: http://www.cplusplus.com/reference/cstring/memcmp/

0
Xiangyi Meng

右。 mostでは、Cのすべての実装ではない場合、配列識別子を最初の要素(つまり、最初の要素のアドレス)へのポインタに暗黙的にキャストできます。ここで行っているのは、これらのアドレスを比較することです。これは明らかに間違っています。

代わりに、両方の配列を反復処理して、各要素を相互に確認する必要があります。失敗せずに両方の最後に到達した場合、それらは等しくなります。

0
slugonamission

配列を使用する場合、実際には配列の最初の要素へのポインターを使用しています。したがって、この条件if( iar1 == iar2 )は実際に2つのアドレスを比較します。これらのポインターは同じオブジェクトをアドレスしません。

0
vladinkoc