web-dev-qa-db-ja.com

C ++でポインタを使用して配列を交換します

スワップする必要があるdoubleへのポインターの配列が2つあります。配列内のデータを単にコピーするよりも、配列へのポインターを交換するだけの方が効率的です。配列名は本質的に単なるポインタであるという印象を常に受け​​ていましたが、次のコードはコンパイラエラーを受け取ります。

double left[] = {1,2,3};
double right[] = {9,8,7};

double * swap = left;
left = right; // Error "ISO C++ forbids assignment of arrays"
right = swap; // Error "incompatible types in assignment of `double*' to `double[((unsigned int)((int)numParameters))]'"

配列を動的に作成すると問題は解決しますが、私のアプリケーションでは実行できません。これを機能させるにはどうすればよいですか?

13
thornate
double array_one[] = {1,2,3};
double array_two[] = {9,8,7};

double *left = array_one;
double *right = array_two;

double * swap = left;
left = right;
right = swap;

うまく機能します。

編集: array_oneとarray_twoの定義は使用しないでください。また、double leftとdouble rightは、元の左右の定義と同じくらい公開する必要があります。

12
Daniel

配列はポインタと同じではなく、説明した方法で交換することはできません。ポインタ交換のトリックを行うには、ポインタを使用するか、メモリを動的に割り当てるか、ポインタを使用してデータにアクセスする必要があります(ダニエルが説明した方法で)。

12
5ound

Cスタイルの配列はポインタではありませんが、ほとんどのオブジェクトと同様に、標準のstd::swap()と交換できます。

#include <iostream>
#include <utility>
int main()
{
        double array_one[] = {1,2,3};
        double array_two[] = {9,8,7};
        std::swap(array_one, array_two);
        std::cout << "array_one[0] = " << array_one[0] << '\n';
        std::cout << "array_two[0] = " << array_two[0] << '\n';
}

実際、配列のstd :: swap()はC++ 0x(20.3.2)でのみ定義されているように見えるので、気にしないでください。正解は、スコープ内の配列と最初の要素へのポインターとしての配列の両方についてです。

 std::swap_ranges(array_one, array_one + 3, array_two);
5
Cubbi

ポインタではなく、簡単に交換できないことを人々に納得させる最も簡単な方法の1つは、次のコードを表示することです。

struct ex {
  char c[4];
  double d[3];
};
struct ex a = {"foo", {1.0, 2.0, 3.0} };
struct ex b = {"bar", {6,7,8} };

明らかにa.db.dは配列です。配列{6,7,8}はa.c=="foo"の後にメモリで終了する必要があるため、それらを交換するには大変な作業が必要になります。つまり、3つのdoubleをコピーします。写真にはポインターがありません。

2
MSalters

参照によって両方のポインターを配列に渡すことができます。ポインターがconstでない場合は、それらを交換するだけです。

void swap(char * & first, char * & second)
{
     std::swap(first, second);
}
0
UnknownGosu

これを試して

double *right = (double[]){9,8,7};
double *left = (double[]){8,2,3};   
0
Charles Ma