2012-04-14 8 views
1

C++に問題があります。参照渡しではなく値渡しの配列を送信するC++

私は配列をソートする関数を持っていますが、元の配列では動作しません。私は参照ではなく値によって関数に配列を送りたい。私を助けてください。

int bogoSort(int tab[], int n){ 
int iloscOperacjiDominujacych = 0; 
    cout<<"rozpoczalem algorytm BogoSort"<<endl; 

    srand (time(NULL)); 
    named (outer) 
    while(true){ 
//  cout<<"Zaczal sie while"<<endl; 
     named (inner) 
     for(int i = 0; i < n; i++){ 
      if(i == n-1){ 
       break (outer); 
      } 
      if (tab[i] > tab[i+1]){ 
       break (inner); 
      } 
     } 
     for(int i = n-1; i > 0; i--){ 
      iloscOperacjiDominujacych++; 
      //operacja dominujaca to zamiana dwoch elementow w tablicy, wykonuje sie ZAWSZE najwiecej razy i jest najbardziej zlozona 
      int swapPostition = rand() % (i+1); //wylosowanie liczby miedzy <0;i> nalezacej do calkowitych 
      int temp = tab[i]; 
      tab[i] = tab[swapPostition]; 
      tab[swapPostition] = temp; 
     } 
    } 
// cout<<"Wykonal sie while"<<endl; 
    show(tab,n); 
    return iloscOperacjiDominujacych; 
} 

答えて

8

C++で配列を値渡しする方法はありません。元の配列を変更したくない場合は、別のコピーを作成して操作するか、std::vectorまたはstd::array(C++ 11を使用している場合)を使用して渡してくださいあなたコピーstd::vectorまたはarrayです)。

+0

どのように効率的に配列をコピーするには(シンプルな配列ではなくコレクション)?迅速な答えをありがとう。 – Yoda

+1

@RobertKilar同じサイズの別の配列を作成し、元の配列から新しい配列に要素をコピーするために 'std :: copy'を使い、コピーを関数に渡します。 –

3

は、値によってCスタイルの配列を渡すことはできません。物語の終わり。

しかし、にはの配列を含む値でクラス型の変数を渡します。これを利用する最も簡単な方法は、std::arrayを使用することです:

void f(std::array<int, 10> a); 

std::array<int, 10> a; 
f(a); 

クラスは、基本的にstruct { int data[10]; };のようなだけで何かですので、あなたが本当にしたい場合、あなたも、この自分をロールバックできます。

4

C++「は、Tの配列」または「Tを返す関数」が「Tへのポインタ」または「ポインタとなるように調整されているタイプの任意のパラメータ、各パラメータのタイプを決定した後関数宣言

について言いますTを返す関数、」だからではなく、C++は、元の配列の最初の要素へのポインタを渡す終わる配列を渡したいとき[dcl.fct] 8.3.5/5

へコピーを作成してvalで渡すueは他のタイプと一貫しています。これはCの互換性の残念な結果であり、なぜ私はこの不一致が良い考えであるとCが考えているのか分かりません。

いずれの場合でも、C++は、静的サイズの配列にはstd::array、動的サイズの配列にはstd::vectorを提供します。可能であれば、C配列を使用しないでください。

int bogoSort(std::vector<int> tab){ 

ないこと:あなたが静的にstd::arrayサイズに使用することはできませんとstd::vectorを使用しなければならないので、

int tab[]は、不明の配列が結合している(あなたがそれらを避けることができない状況はめったにありません)ベクトルは独自のサイズを知っているため、nパラメータは必要ありません。これはstd :: vectorとstd :: arrayが配列よりも安全な方法の1つです。また、ベクトルがそのサイズを記憶することに伴う余分なオーバーヘッドを持っているにもかかわらず、オーバーヘッドは実質的にゼロです。なぜなら、あなたは他の場所でその作業を行う必要がないからです。


本当にC配列(実際には使用しないでください)を取りたい場合は、手動で簡単にコピーできます。

int bogoSort(int const *tab,int n) { 
    std::vector<int> tab_copy(tab,tab+n); 
    bogoSort(tab_copy); 
} 

int bogoSort(std::vector<int> tab) { 
    ... 
} 

ご覧のとおり、内部的にはベクターを使用していますが、ベクターを使用するbogoSortのオーバーロードがあります。コピーを生の配列にすることと比較してください:

int bogoSort(int const *tab,int n) { 
    int *tab_copy = new int[n]; 
    std::copy(tab,tab+n,tab_copy);    // manual copying 
    bogoSort_impl(tab_copy,n);     // not overloading, hidden internal function 
    delete [] tab_copy;      // resource cleanup. We're not exception safe! 
} 

// or 

int bogoSort(int const *tab,int n) { 
    // unqiue_ptr for exception safety 
    std::unqiue_ptr<int[]> tab_copy = std::unqiue_ptr<int[]>(new int[n]); 
    std::copy(tab,tab+n,tab_copy.get()); 
    bogoSort_impl(tab_copy.get(),n); 
} 

また、実際にはC配列を使用すべきではありません。彼らはあまりにも多くのトラブルと利点はありません。

関連する問題