0

編集:グローバルまたは静的でなく、ベクトルまたは動的ベクトルなしでそれを実行しようとするとどうなりますか?

2 つのベクトルを作成し、2 つの配列の各要素の商である新しいベクトルをアドレス渡しする関数を用意しようとしています。つまり、V1 は 1 1 2 2 3 4 V2 は 2 2 1 1 2 2 期待される結果は 2 2 2 2 6 8 です。

私の問題は、乱数を受け取るため、「quoziente」関数から「r」の結果を送信するときです。問題は、関数が実行中にのみ存在することですが、実行を停止すると変数も一緒に死ぬことだと思います。どうすればいいですか?「ris」に正しいアドレスを渡していることは確かです。操作の要素を印刷しようとしましたが、正しい操作を行っていると確信しています。どんな助けでも本当に感謝しています! ありがとう

コードは次のとおりです。

  1 #include <iostream>
  2 using namespace std;
  3
  4
  5
  6 void readarray (int* v, int dim) { 
  7     for(int i=0; i<dim; i++) { 
  8         cin >> v[i];
  9     } 
 10 }
 11 
 12 void printarray(int* v, int dim) { 
 13     for(int i=0; i<dim; i++) { 
 14         cout << v[i] << " ";
 15     } 
 16     cout << endl;
 17 }
 18 
 19 int main() { 
 20     int v1[7];
 21     int v2[7];
 22     int *ris;
 23       
 24     cout << "V1";
 25     readarray(v1,7);
 26     cout << "V2";
 27     readarray(v2,7);
 28     ris = quoziente(v1,v2,7);
 29     cout << "V1";
 30     printarray(v1,7);
 31     cout << "V2";
 32     printarray(v2,7);
 33     cout << "ris ";
 34     printarray(ris,7);
 35     
 36     return 0;
 37 } 
 38 
 39 int* quoziente (int* v1, int* v2, int dim) { 
 40     int r[7]; 
 41 
 42     for(int i=0; i<dim; i++) { 
 43        r[i] = v1[i] * v2[i];
 44        cout << r[i] << " ";
 45     }
 46     cout << endl;
 47     return r;
 48 }
4

6 に答える 6

3

r はスタック上で宣言されているため、範囲外になると削除されます。たとえば、ヒープにメモリを割り当てる必要があります

int *r = new int[7]; // * was missing

使い終わったら必ず呼び出しdelete [] ris;て、割り当てたメモリを解放してください

于 2013-09-02T10:33:44.260 に答える
2

関数 quoziente() 内で、

int r[7]; <-- これはスタックに割り当てられているため、関数が戻ると死にます。

問題を解決する別の方法:-

1) quozinete() 内で r を動的に割り当てます。

int *r = new int [7];

2) r を static として宣言します。

static int r[7];

3) r をグローバルスコープに入れます。

4) r を v1 および v2 と共に main で次のように宣言します。

int v1[7];
int v2[7];
int r[7];

quozinete のプロトタイプを次のように変更します。

void quoziente (int* v1, int* v2, int dim, int *r)

つまり、結果配列のポインターを別のパラメーターとして関数に渡します。

于 2013-09-02T10:47:40.853 に答える
1

関数で定義する他の回答配列で説明されている理由は一時的なものです。関数が存在するまで存在します。risこの問題を解決する別の方法は、他の 2 つの配列 v1 および v2 と同じサイズの、ポインターではなく名前付きの配列を定義することです。それを引数として関数に渡し、関数を次のように変更します

void quoziente (int* r, int* v1, int* v2, int dim) {  
  for(int i=0; i<dim; i++) { 
    r[i] = v1[i] * v2[i];
   cout << r[i] << " ";
 }
}

関数の呼び出し中に res を引数として渡すquoziente

quoziente(ris,v1,v2,7)

2番目の解決策は、他の回答ですでに説明されているように、 new 演算子を使用して配列を動的に割り当てることです。ただし、メイン関数で使用されていない場合は、配列を削除することを忘れないでください。関数コードにアクセスできない場合、 main() 関数で配列を削除する必要があることを知る方法がないため、これは推奨されない方法です。また、関数にアクセスできる場合でも、通常は削除するのを忘れます。

変数/配列を静的に宣言する 3 番目の解決策もお勧めしません。別の配列割り当てに関数を再利用すると、以前に割り当てられた配列も変更されるためです。

于 2013-09-02T11:05:14.550 に答える
1

たとえば、r次のようにします。

int *r = new int[7];

ただし、後で削除する必要があります。

または静的にする

static int r[7];

削除する必要はありません。ただし、すべての関数呼び出しで共有されるため、2 回呼び出すことはできず、ポインターを保持し、結果が同じままであることを期待できます。

于 2013-09-02T10:33:55.763 に答える
1

他の回答で問題をすでに把握している可能性があります

STLアルゴリズムを使用して同じことを達成する別の方法を紹介します

std::transformラムダ関数

  int v1[7];
  int v2[7];
  int ris[7];

  std::transform(std::begin(v1), std::end(v1), 
             std::begin(v2), 
              std::begin(ris),
           [](const int &x, const int &y){ return x*y;}
                      );

デモを見る

于 2013-09-02T10:47:11.210 に答える