你能在C中将算术运算符实现为变量吗?

min*_*h b 4 c arithmetic-expressions postfix-notation

我正在尝试编写一个反向波兰计算器,但我不想为输入的每个算术运算符编写开关。是否可以输入算术运算符并在语言本身内部使用它?

例如,程序可以提示用户输入算术运算符 for:,
a = b [whatever operator here] c;

并且某些变量将存储该运算符。假设是+,我们得到:
a = b + c;

这是可能的还是我应该把它吸收并为操作员编写开关?

klu*_*utt 11

简短回答:

不,这是不可能的。至少不是你想要的方式。

长答案:

你不能。C 根本不支持evalPython 中的函数之类的东西。对于那些不知道它是什么的人,这将打印“Hello”:

s = "print('Hello')" # A string with the code we want to execute
eval(s)              # Evaluate the string s as python code and execute it
Run Code Online (Sandbox Code Playgroud)

如果你想在 C 中做类似的事情,那就算了。这是不可能的。

您可以使用函数指针实现类似的目标。如果您不习惯函数指针,它看起来会很尴尬,但它模仿了您正在谈论的内容。虽然很糟糕。

int add(int a, int b) { return a+b; }
int sub(int a, int b) { return a-b; }

// Function taking two int and returning int
typedef int (operation)(int, int);

int main(void) {
    operation *ops[UCHAR_MAX+1];
    ops['+'] = add;
    ops['-'] = sub;
    printf("Sum:  %d\nDiff: %d\n", ops['+'](5,3), ops['-'](5,3));    
}
Run Code Online (Sandbox Code Playgroud)

这打印:

int add(int a, int b) { return a+b; }
int sub(int a, int b) { return a-b; }

// Function taking two int and returning int
typedef int (operation)(int, int);

int main(void) {
    operation *ops[UCHAR_MAX+1];
    ops['+'] = add;
    ops['-'] = sub;
    printf("Sum:  %d\nDiff: %d\n", ops['+'](5,3), ops['-'](5,3));    
}
Run Code Online (Sandbox Code Playgroud)

ops是一个函数指针数组。更准确地说,是“指向返回 int 的函数 (int, int) 的指针数组 256”。所以我们直接使用单个字符来索引它。

这里需要注意的一件事是确保没有负值传递给ops. char这可能发生在默认签名的计算机上。

如果您希望错误处理形式具有一定的安全性,您可以执行以下操作:

int error(int a, int b) {
    fprintf(stderr, "Function not implemented");
    exit(EXIT_FAILURE);
}
Run Code Online (Sandbox Code Playgroud)

然后执行以下操作:

operation *ops[UCHAR_MAX+1];
for(int i=0; i < sizeof ops/sizeof *ops; i++) 
    ops[i] = error;

ops['+'] = add;
ops['-'] = sub;
Run Code Online (Sandbox Code Playgroud)

如果您只想支持四个操作,则此方法不值得所有这些额外的麻烦,但如果您正在编写模拟器,它实际上会非常方便。我观看了一个关于编写 NES 模拟器的非常有趣的 YouTube 播放列表。它是用 C++ 编写的,但是非常老派,所以如果您了解 C,那么理解它并不难。他在第 2 部分中讨论了函数指针。

https://youtu.be/F8kx56OZQhg

注意:不是我的频道。我与此完全无关。正在犹豫,因为它可能看起来像垃圾邮件,但这些视频对于编码员来说确实很有趣。

  • @Zakk - 一旦你达到大约 30 个案例标签左右,你就会有不同的想法。 (7认同)
  • @TedLyngmo 是的,我觉得有点奇怪。这不仅是一个很好的方法。这也是唯一的方法。:) (2认同)