简体   繁体   English

在C中使用递归函数时,避免使用全局变量

[英]Avoid using global variables when using recursive functions in C

The code below uses a recursive function called interp , but I cannot find a way to avoid using global variables for iter and fxInterpolated . 下面的代码使用一个名为interp的递归函数,但我找不到避免使用iterfxInterpolated的全局变量的方法 The full code listing (that performs N-dimensional linear interpolation) compiles straightforwardly with: 完整的代码清单(执行N维线性插值)直接编译:

gcc NDimensionalInterpolation.c -o NDimensionalInterpolation -Wall -lm

The output for the example given is 2.05. 给出的示例的输出是2.05。 The code works fine but I want to find alternatives for the global variables. 代码工作正常,但我想找到全局变量的替代品。 Any help with this would be greatly appreciated. 任何有关这方面的帮助将不胜感激。 Thanks. 谢谢。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int linearInterpolation(double *, double **, double *, int);
double ** allocateDoubleMatrix(int, int);
double * allocateDoubleVector(int);
void interp(int, int, double *, double *, double *);
double mult(int, double, double *, double *);

/* The objectionable global 
variables that I want to get rid of! */

int iter=0;
double fxInterpolated=0;

int main(int argc, char *argv[]){

 double *fx, **a, *x;
 int dims=2;

 x=allocateDoubleVector(dims);
 a=allocateDoubleMatrix(dims,2);
 fx=allocateDoubleVector(dims*2);

 x[0]=0.25;
 x[1]=0.4;

 a[0][0]=0;
 a[0][1]=1;
 a[1][0]=0;
 a[1][1]=1;

 fx[0]=1;
 fx[1]=3;
 fx[2]=2;
 fx[3]=4;
 linearInterpolation(fx, a, x, dims);
 printf("%f\n",fxInterpolated);

 return (EXIT_SUCCESS);

 } 

 int linearInterpolation(double *fx, double **a, double *x, int dims){

  double *b, *pos;
  int i;

  b=allocateDoubleVector(dims);
  pos=allocateDoubleVector(dims);

  for (i=0; i<dims;i++)
   b[i] = (x[i] - a[i][0]) / (a[i][1] -  a[i][0]);

  interp(0,dims,pos,fx,b); 

  return (EXIT_SUCCESS);

}  

void interp(int j, int dims, double *pos, double *fx, double *b) {

int i;

if (j == dims){
  fxInterpolated+=mult(dims,fx[iter],pos,b);
  iter++;
  return;
}

 for (i = 0; i < 2; i++){
   pos[j]=(double)i; 
   interp(j+1,dims,pos,fx,b);
 }

}

double mult(int dims, double fx, double *pos, double *b){

 int i;
 double val=1.0; 

 for (i = 0; i < dims; i++){
  val *= fabs(1.0-pos[i]-b[i]); 
 } 
 val *= fx;

 printf("mult val= %f fx=%f\n",val, fx);
 return val;

}

double ** allocateDoubleMatrix(int i, int j){

 int k;
 double ** matrix;
 matrix = (double **) calloc(i, sizeof(double *));
 for (k=0; k< i; k++)matrix[k] = allocateDoubleVector(j);
 return matrix;
}

 double * allocateDoubleVector(int i){
  double *vector;
  vector = (double *) calloc(i,sizeof(double));
  return vector;
}

Thanks for the comments so far. 感谢您的评论到目前为止。 I want to avoid the use of static. 我想避免使用静态。 I have removed the global variable and as suggested tried parsing with the iter variable. 我删除了全局变量,并且建议尝试使用iter变量进行解析。 But no joy. 但没有快乐。 In addition I am getting a compile warning: "value computed is not used" with reference to *iter++; 另外我得到一个编译警告:“不使用值计算”参考* iter ++; What am I doing wrong? 我究竟做错了什么?

void interp(int j, int dims, double *pos, double *fx, double *b, int *iter) {

int i;

if (j == dims){
fxInterpolated+=mult(dims,fx[*iter],pos,b);
*iter++;
return; 
}

 for (i = 0; i < 2; i++){
  pos[j]=(double)i; 
  interp(j+1,dims,pos,fx,b,iter);
 }

} }

There are two approaches I would consider when looking at this problem: 在查看此问题时,我会考虑两种方法:

Keep the state in a parameter 将状态保存在参数中

You could use one or more variables that you pass to the function (as a pointer, if necessary) to keep the state across function calls. 您可以使用一个或多个传递给函数的变量(如果需要,作为指针)以保持函数调用之间的状态。

For instance, 例如,

int global = 0;
int recursive(int argument) {
  // ... recursive stuff
  return recursive(new_argument);
}

could become 可能成为

int recursive(int argument, int *global) {
  // ... recursive stuff
  return recursive(new_argument, global);
}

or sometimes even 有时甚至是

int recursive(int argument, int global) {
  // ... recursive stuff
  return recursive(new_argument, global);
}

Use static variables 使用静态变量

You can also declare a variable in a function to be preserved across function calls by using the static keyword: 您还可以使用static关键字在函数调用中声明要保留的函数中的变量:

int recursive(int argument) {
  static int global = 0;
  // ... recursive stuff
  return recursive(argument);
}

Note that because of the static keyword, global = 0 is only set when the program starts, not every time the function is called, as it would be without the keyword. 请注意,由于static关键字, global = 0仅在程序启动时设置,而不是每次调用函数时都设置,因为没有关键字。 This means that if you alter the value of global , it would keep this value the next time the function is called. 这意味着如果改变global的值,它将在下次调用函数时保留该值。

This method can be used if you only use your recursive function once during your program; 如果在程序中只使用一次递归函数, 可以使用此方法; if you need to use it multiple times, I recommend that you use the alternative method above. 如果你需要多次使用它,我建议你使用上面的替代方法。

A solution is to use statics and then to reset the variables on the first call, via a flag that I call initialise. 一个解决方案是使用静态,然后通过我调用初始化的标志在第一次调用时重置变量。 That way you can choose to have the variables reset or not. 这样你可以选择重置或不重置变量。

double interp(int j, int dims, double *pos, double *fx, double *b, int initialise) {

 static double fxInterpolated = 0.0;
 static int iter = 0; 
 int i;


 if (initialise){
  fxInterpolated = 0.0;
  iter = 0;
 }

 .....
......
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM