将函数作为参数传递

时间:2011-03-06 08:04:17

标签: c

在C中启动程序时,有没有办法将函数作为参数传递?我正在实现一个用于积分近似的应用程序,我需要的是在启动应用程序时键入我想要使用的函数。我试过(例如)2/(2+2*x),但我只回到“2”。当我直接写应用程序时,没有问题。有没有简单的方法来获得这个?也许将其重新分配给更多参数?喜欢

app.c number number*x number *x*x number *x*x*x... ?

由于

3 个答案:

答案 0 :(得分:2)

不幸的是,C中没有内置的表达式求值程序。如果你只需要简单的表达式,并且语法不那么重要,你可以使用反向抛光表示法,正如HP计算器使用的那样背部。该系统使用堆栈,输入数字将其推入堆栈,从堆栈输入操作弹出值,计算并推回它们。没有必要处理括号,因为表达式通常是从里面写出来的。

例如,2 * x将写为:

app 2 x mul

例如,您的原始表达式可以写为:

app 2 2 2 x mul add div

我将实现作为练习,你不应该只需要一页代码。

答案 1 :(得分:1)

这不是答案。只是为了表明它并不复杂:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

typedef struct expr_s {
    char op;
    struct expr_s *exprA, *exprB;
    float value;
} expr;

int readExpr(expr *node, int argc, char *argv[]) {
    int argn = 1;
    assert(argc > 0);
    switch(argv[0][0]) {
    case '0' ... '9':
    case '-': case '.':
        node->op = '#'; // direct value
        node->value = atof(argv[0]);
        return 1;
    case 'x':
        if (argv[0][1] == '\0') { // variable
            node->op = 'x';
            return 1;
        }
        break;
    default: ;
    }
    // binary expr
    if (strcmp(argv[0], "mul") == 0) node->op = '*';
    else if (strcmp(argv[0], "add") == 0) node->op = '+';
    else if (strcmp(argv[0], "div") == 0) node->op = '/';
    else if (strcmp(argv[0], "sub") == 0) node->op = '-';
    else abort();
    node->exprA = (expr*)malloc(sizeof(expr));
    node->exprB = (expr*)malloc(sizeof(expr));
    argn += readExpr(node->exprA, argc-argn, argv+argn);
    argn += readExpr(node->exprB, argc-argn, argv+argn);
    return argn;
}

float evalExpr(expr *node, float x) {
    switch(node->op) {
    case '#': return node->value;
    case 'x': return x;
    case '*': return (evalExpr(node->exprA, x) * evalExpr(node->exprB, x));
    case '+': return (evalExpr(node->exprA, x) + evalExpr(node->exprB, x));
    case '/': return (evalExpr(node->exprA, x) / evalExpr(node->exprB, x));
    case '-': return (evalExpr(node->exprA, x) - evalExpr(node->exprB, x));
    default: abort();
    }
}

int main(int argc, char *argv[]) {
    expr rootExpr;
    float x;
    readExpr(&rootExpr, argc-1, argv+1);
    for(x=0; x < 5; x+=0.5) {
        printf("f(%f) = %f\n", x, evalExpr(&rootExpr, x));
    }
    return 0;
}

Rusult:

./playground div 2 add 2 mul 2 x
f(0.000000) = 1.000000
f(0.500000) = 0.666667
f(1.000000) = 0.500000
f(1.500000) = 0.400000
f(2.000000) = 0.333333
f(2.500000) = 0.285714
f(3.000000) = 0.250000
f(3.500000) = 0.222222
f(4.000000) = 0.200000
f(4.500000) = 0.181818

请注意,如果您使用反向抛光表示法,您会看到几乎相同,但如果后续调用expr,则会显示readExpr堆栈。

答案 2 :(得分:0)

一个简单的方法是将表达式存储在一个文件中,为程序提供该文件的名称作为参数,然后使用system()或等效的shell来解释和评估表达式在运行时。然而,这将是相当缓慢的。

如果你想要更高的性能,并且你的功能不是非常复杂(例如你只有基本的算术运算),那么你可以编写一个递归函数来评估它。从公式结束开始,向后走,找到优先级最低的操作。递归计算双方,然后将操作应用于结果。如果找不到运算符,请检查表达式周围的括号,并评估内部。如果没有括号,则整个表达式是单个值,并且可以转换为double(表面上)。