在C ++中通过引用传递数组

时间:2015-06-24 03:30:12

标签: c++ arrays function argument-passing

我有一个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的第i个元素对应vecs的第i列(在Fortran的列主要顺序中)。为了避免在C ++中使用多维数组,我只是将vecs表示为esort中的一维数组。 esort的重点是对lambda进行排序,然后重新排序vecs,使lambda的第i个元素仍然对应vecs的第i列。

编辑2 :在cout内放置esort个语句,我确认res_lamres_vec具有我想要的值在例行程序结束时。我的问题是将这些值返回给调用程序。

3 个答案:

答案 0 :(得分:1)

C ++确实按值传递了所有参数,包括指针,这意味着分配给vecscopy对调用者没有影响:这些变量只有 point 对数据。您需要将结果复制到指向内存中,如下所示,使用<algorithm>中的rbeginrendsort也是反向迭代器,它会导致begin从您想要的位置向后排序;我将其更改为endvector。我建议您使用res_lam作为临时res_vec#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); } 数组。

ggplot() + geom_histogram(data = resultsPileup1COMBINED[resultsPileup1COMBINED$log2_ratio > 0, ], 
                          aes(x = log2_ratio, y = ..count..)) + 
           geom_histogram(data = resultsPileup1COMBINED[resultsPileup1COMBINED$log2_ratio < 0, ], 
                          aes(x = - log2_ratio, y = - ..count..))

答案 1 :(得分:0)

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

调用此函数时,它会创建引用相同内存地址的本地指针变量。在完成以下操作的代码中:

lambda = res_lam;
vecs = res_vec;

这并不意味着您要将作为参数传递的内存地址的值更改为函数,而是函数lambdavecs的本地指针变量现在指向一个不同的内存地址。

答案 2 :(得分:0)

或者,您可以使用Pointer to Pointer Concept。

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