簡體   English   中英

在C ++中通過引用傳遞數組

[英]Pass array by reference in C++

我有一個Fortran代碼,在其中需要對彼此相關的兩個數組進行排序。 我想在C ++函數中執行此操作,以便利用STL中的內置排序算法。 因為Fortran是傳遞引用,所以C ++函數的所有參數都必須是指針。 以下函數esort對數組正確排序,但不會返回正確的值。 我相信這是因為指針是按值傳遞的,所以函數末尾的更新無效。 我應該如何更改代碼以達到預期的效果?

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

void esort(double* lambda, double* vecs, int* n) {

  double* res_lam = new double[*n];
  double* res_vec = new double[*n * *n];
  vector<pair<double, int> > order(*n);

  for (int i=0; i<*n; i++) {
    order[i] = make_pair(lambda[i], i);
  }

  sort(order.rbegin(), order.rend());

  for (int i=0; i<*n; i++) {
    pair<double, int> p = order.at(i);
    res_lam[i] = p.first;
    for (int j=0; j<*n; j++) {
      res_vec[*n*i + j] = vecs[*n*p.second + j];
    }
  }

  lambda = res_lam;
  vecs = res_vec;

  delete [] res_lam;
  delete [] res_vec;

  return;
}

int main() {

  double lambda[] = {0.5, 2.0, 1.0};
  double vecs[] = {0.5, 0.5, 0.5, 2.0, 2.0, 2.0, 1.0, 1.0, 1.0};
  int n = 3;

  esort(lambda, vecs, &n);

  cout << "lambda" << endl;
  for (int i=0; i<n; i++) {
    cout << lambda[i] << " ";
  }
  cout << endl;
  cout << "vecs" << endl;
  for (int i=0; i<n; i++) {
    for (int j=0; j<n; j++) {
      cout << vecs[j*n + i] << " ";
    }
    cout << endl;
  }

  return 0;
}

輸出:

lambda
0.5 2 1 
vecs
0.5 2 1 
0.5 2 1 
0.5 2 1

所需輸出:

lambda
0.5 1 2 
vecs
0.5 1 2 
0.5 1 2 
0.5 1 2

編輯: lambda的ith元素對應於vecs的ith列(按Fortran的列順序)。 為了避免在C ++多維數組hassling,我只是代表vecs作為內一維數組esort esort是排序lambda然后重新排列vecs ,使得第i個元素lambda仍然對應於第i列vecs

編輯2:通過將cout語句中esort ,我已經證實, res_lamres_vec有,我希望他們有在程序結束時的值。 我的問題是將這些值返回給調用程序。

C ++確實按值傳遞其所有參數(包括指針),這意味着分配給lambdavecs對調用方沒有影響:這些變量僅指向數據。 您需要將結果復制到該指向的內存中,如下所示,使用<algorithm> copy rbeginrend都是反向迭代器,它使sort從所需的內容向后排序。 我將其更改為beginend 我會進一步建議對您的臨時res_lamres_vec數組使用vector

#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>

using namespace std;

void esort(double* lambda, double* vecs, int* n) {

  vector<double> res_lam(*n);
  vector<double> res_vec(*n * *n);
  vector<pair<double, int> > order(*n);

  for (int i=0; i<*n; i++) {
    order[i] = make_pair(lambda[i], i);
  }

  sort(order.begin(), order.end());

  for (int i=0; i<*n; i++) {
    pair<double, int> p = order.at(i);
    res_lam[i] = p.first;
    for (int j=0; j<*n; j++) {
      res_vec[*n*i + j] = vecs[*n*p.second + j];
    }
  }

  copy(res_lam.begin(), res_lam.end(), lambda);
  copy(res_vec.begin(), res_vec.end(), vecs);
}

void esort(double* lambda, double* vecs, int* n)

調用此函數時,它將創建引用相同內存地址的局部指針變量。 在代碼中完成以下操作時:

lambda = res_lam;
vecs = res_vec;

這並不意味着您要更改作為參數傳遞給函數的內存地址的值,而是函數lambdavecs的本地指針變量現在指向另一個內存地址。

或者,您可以使用“指針到指針”概念。

void esort(double** lambda, double** vecs, int* n)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM