[英]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_lam
和res_vec
有,我希望他們有在程序結束時的值。 我的問題是將這些值返回給調用程序。
C ++確實按值傳遞其所有參數(包括指針),這意味着分配給lambda
和vecs
對調用方沒有影響:這些變量僅指向數據。 您需要將結果復制到該指向的內存中,如下所示,使用<algorithm>
copy
。 rbegin
和rend
都是反向迭代器,它使sort
從所需的內容向后排序。 我將其更改為begin
和end
。 我會進一步建議對您的臨時res_lam
和res_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;
這並不意味着您要更改作為參數傳遞給函數的內存地址的值,而是函數lambda
和vecs
的本地指針變量現在指向另一個內存地址。
或者,您可以使用“指針到指針”概念。
void esort(double** lambda, double** vecs, int* n)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.