【问题标题】:Dynamic creation of a pointer function in c++在 C++ 中动态创建指针函数
【发布时间】:2010-04-04 21:01:41
【问题描述】:

我今天正在做我的高级微积分作业,我们正在按照牛顿法的思路进行一些迭代方法,以找到诸如 x^2=2 之类的解决方案。这让我想到我可以编写一个函数,它需要两个函数指针,一个指向函数本身,一个指向衍生函数并自动化该过程。这不会太具有挑战性,然后我开始思考是否可以让用户输入一个函数并解析该输入(是的,我可以这样做)。但是我是否可以在 C++ 中动态创建一个指向单变量函数的指针。例如,如果 x^2+x,我可以在运行时创建一个函数 double function(double x){ return x*x+x;}。这是远程可行的,还是沿着自修改代码行?

编辑:

所以我想如果你将信息存储在一个数组中并且有一个函数可以用给定的输入评估存储在这个数组中的信息,那么我想如何做到这一点。然后您可以创建一个类并在该类中初始化数组,然后从那里使用该函数。有没有更好的办法?

【问题讨论】:

标签: c++ math pointers function


【解决方案1】:

正如其他人所说,您不能在运行时以任何可移植的方式创建新的 C++ 函数。但是,您可以创建一个表达式评估器来评估以下内容:

 (1 + 2) * 3

包含在一个字符串中,在运行时。将这样的求值器扩展为具有变量和函数并不难。

【讨论】:

    【解决方案2】:

    你不能动态地创建一个函数,因为你可以为它生成原始机器代码,但你可以很容易地使用多态性创建数学表达式:

    struct Expr
    {
      virtual double eval(double x) = 0;
    };
    
    struct Sum : Expr
    {
      Sum(Expr* a, Expr* b):a(a), b(b) {}
      virtual double eval(double x) {return a->eval(x) + b->eval(x);}
    private:
      Expr *a, *b;
    };
    
    struct Product : Expr
    {
      Product(Expr* a, Expr* b):a(a), b(b) {}
      virtual double eval(double x) {return a->eval(x) * b->eval(x);}
    private:
      Expr *a, *b;
    };
    
    struct VarX : Expr
    {
      virtual double eval(double x) {return x;}
    };
    
    struct Constant : Expr
    {
      Constant(double c):c(c) {}
      virtual double eval(double x) {return c;}
    private:
      double c;
    };
    

    然后,您可以在运行时将表达式解析为 Expr 对象。例如,x^2+x 将是 Expr* e = new Sum(new Product(new VarX(), new VarX()), new VarX())。然后,您可以使用e->eval(x) 对给定的 x 值进行评估。

    注意:在上面的代码中,为了清楚起见,我忽略了 const 正确性——你不应该 :)

    【讨论】:

      【解决方案3】:

      它类似于自修改代码,而且是可能的——只是不是在“纯”C++ 中。您需要了解一些程序集和一些实现细节。在不走这条路的情况下,您可以抽象地表示操作(例如使用函子)并构建要评估的表达式树。

      但是,对于您只给出一个变量的简单情况,您只需要存储系数,就可以轻松地评估给定值的系数。

      // store coefficients as vector in "reverse" order, e.g. 1x^2 - 2x + 3
      // is stored as [3, -2, 1]
      typedef double Num;
      typedef vector<double> Coeffs;
      Num eval(Coeffs c, Num x) {
        assert(c.size()); // must not be empty
        Num result = 0;
        Num factor = 1;
        for (Coeffs::const_iterator i = c.begin(); i != c.end(); ++i) {
          result += *i * factor;
          factor *= x;
        }
        return result;
      }
      
      int main() {
        Coeffs c;       // x^2 + x + 0
        c.push_back(0);
        c.push_back(1);
        c.push_back(1); 
        cout << eval(c, 0) << '\n';
        cout << eval(c, 1) << '\n';
        cout << eval(c, 2) << '\n';
      }
      

      【讨论】:

      • 这仅适用于多项式...如果表达式是x^x
      【解决方案4】:

      您实际上并不需要为此自行修改代码。但是您将编写归结为表达式解析器和解释器的内容。您编写代码以将您的函数解析为合适的数据结构(例如树)。对于给定的输入,您现在遍历树并计算函数的结果。可以通过访问者进行计算。

      【讨论】:

        【解决方案5】:

        你不需要知道汇编。为可能的表达式编写 c++ 代码,然后编写一个编译器来检查表达式并选择适当的代码 sn-ps。这可以像解释器通常那样在运行时完成,或者它可以是一个编译阶段,它通过将每个表达式评估中的指令复制到分配的内存中来创建要执行的代码,然后将其设置为一个函数。后者更难理解和编码,但性能更好。但是为了使开发时间加上执行时间少于解释实现,编译后的代码必须使用很多(数十亿)次。

        【讨论】:

          【解决方案6】:

          正如其他人所提到的。编写自修改代码根本没有必要,如果您希望它是可移植的,那么在编译语言中会很痛苦。 您工作中最困难的部分是解析输入。我推荐muParser 来评估你的表达。它应该会消除很多痛苦,您将能够专注于项目的重要部分。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-18
            • 2020-12-26
            • 2013-11-26
            • 1970-01-01
            • 1970-01-01
            • 2020-06-28
            相关资源
            最近更新 更多