1

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;
}
4

3 に答える 3

8

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

于 2012-04-14T16:49:14.973 に答える
4

C++ は関数宣言について述べています

各パラメーターの型を決定した後、「T の配列」または「T を返す関数」型のパラメーターは、「T へのポインター」または「T を返す関数へのポインター」になるように調整されます。[dcl.fct] 8.3.5/ 5

したがって、配列を渡したい場合、C++ は、コピーを作成して他の型と一致するように値で渡す代わりに、元の配列の最初の要素へのポインターを渡すことになります。これは C との互換性の不幸な結果であり、C がこの不一致を良い考えだと考えた理由がわかりません。

いずれにせよ、C++ はstd::array静的サイズの配列とstd::vector動的サイズの配列を提供します。C 配列は奇妙なので、可能な限り避けるべきです。(避けられない場合も稀にあります)

int tab[]未知の境界を持つ配列であるため、静的にサイズ設定された を使用することはできず、使用するstd::array必要がありますstd::vector:

int bogoSort(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 配列を使用するべきではありません。彼らはあまりにも面倒で、何のメリットもありません。

于 2012-04-14T17:12:41.673 に答える
3

C スタイルの配列を値で渡すことはできません。話の終わり。

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

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

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

クラスは基本的に のようなものなstruct { int data[10]; };ので、本当にしたい場合は自分でロールすることもできます。

于 2012-04-14T16:55:35.153 に答える