Бесчисленные функции GSL возвращают их результат как указатель в свой первый аргумент. НапримерВозвращение double * в аргументе функции
INT gsl_matrix_get_col (gsl_vector * v, Const gsl_matrix * м, size_t J)
Мой уровень программирования очень низкий, но мне сказали такие вещи были невозможны с локальными переменными (удалены конец функции), но возможно с указателями, если они были объявлены и правильно распределены функцией вызывающего абонента. Я считаю это очень странным, такая фундаментальная разница должна существовать между указателями и нормальными переменными, но я попытался использовать это сохранение результатов в переменных для простой программы GSL, где мне нужна функция (fetch_eigenvalue()), чтобы вывести две вещи , И я терпеть неудачу. Моя программа выглядит следующим образом:
#include <math.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_blas.h>
/* Parameters */
#define N 3
int CREATE_MATRIX_AND_VECTOR(gsl_matrix *m, gsl_vector *v);
double fetch_eigenvalue(gsl_matrix *M, gsl_vector *v, double *rescos);
int main()
{
gsl_matrix *unit_matrix = gsl_matrix_calloc(N, N); //soon to be unity
gsl_vector *v = gsl_vector_calloc(N); //soon to be unit x vector
double *outcos = (double*)malloc(sizeof(double));
printf("**********************************************\n");
CREATE_MATRIX_AND_VECTOR(unit_matrix, v);
fetch_eigenvalue(unit_matrix, v, outcos);
printf("==IN MAIN: outcos = %e\n", *outcos);
free((void *)outcos);
gsl_vector_free(v);
gsl_matrix_free(unit_matrix);
printf("**********************************************\n");
return(0);
}
int CREATE_MATRIX_AND_VECTOR(gsl_matrix * m, gsl_vector *v)
{
int i;
for (i = 0; i < N; i++)
{
gsl_matrix_set(m, i, i, 1.0);
}
gsl_vector_set(v, 0, 1.0);
return(0);
}
double fetch_eigenvalue(gsl_matrix *M, gsl_vector *v, double *rescos) //fetches eigenvalue, if Mv is parallel to v within accuracy gvaccu
//rescos is the cosine of the angle between Mv and v
{
int i,lv;
double v0, v1, cos;
double result;
double vnorm, pnorm;
double rdot;
lv = v->size;
double gvaccu = 1e-10;
gsl_vector *prod = gsl_vector_calloc(lv);
gsl_matrix_get_row(prod, M, 0);
if(gsl_blas_dnrm2(prod)==0.0)
{
result = 0.0;
}
else
{
gsl_blas_dgemv(CblasNoTrans,1.0, M, v, 0.0, prod);
gsl_blas_ddot(prod, v, &rdot);
pnorm = gsl_blas_dnrm2(prod);
vnorm = gsl_blas_dnrm2(v);
cos = rdot/pnorm/vnorm;
cos = fabs(cos);
rescos = &cos;
if(fabs(cos -1.0) > gvaccu)
{
result = -1.0;
}
else
{
v0 = gsl_vector_get(v,0);
v1 = gsl_vector_get(prod,0);
result = v1/v0;
}
}
printf("==IN FETCH_EV: COS = %e\n", cos);//print cheat!!
printf("==IN FETCH_EV: RESCOS = %e\n", *rescos);//print cheat!!
gsl_vector_free(prod);
return(result);
}
я запускаю его и получить следующий вывод:
[email protected]:~/Desktop/Healpix_3.20$ g++ -o wrong_output wrong_output.c -L. -L/sw/lib -I/sw/include -lgsl -lblas && ./wrong_output
**********************************************
==IN FETCH_EV: COS = 1.000000e+00
==IN FETCH_EV: RESCOS = 1.000000e+00
==IN MAIN: outcos = 0.000000e+00
**********************************************
[email protected]:~/Desktop/Healpix_3.20$
Таким образом, вызывающий абонент основной() ничего не знает о том, что произошло в fetch_eigenvalue(), Eventhough я использовал указатель. Что я делаю не так? У меня такое чувство, что я неправильно понял что-то очень важное.
Кстати, вам не нужно явно выделять что-то, чтобы получить указатель переменной. Например, вы могли бы объявить «double outcos;» и вызвали функцию, передающую свой указатель, используя '& outcos'. Что-то вроде [this] (https://ideone.com/kPDYvO). – wendelbsilva