我正在使用 C 编写小型解析器和“方程式求解器”,这个过程的一部分是对标记进行算术运算。 每个 token 都包含指向数值数据的 void* 指针和定义数据类型的枚举。
这是函数示例,它通过添加另外两个标记来创建新标记。为此,我需要
- 支票类型
- Actor
- 做运营
- 根据结果创建新 token
一个
Token* _CreateTokenByAddition(Token* arg1, Token* arg2){
Token *tokenResult;
if ((arg1->_type == tk_IntData) && (arg2->_type == tk_IntData)){
int* intResult = malloc(sizeof(int));
*intResult = *(int*)arg1->_data + *(int*)arg2->_data;
tokenResult = CreateTokenFromValue(intResult, tk_IntData);
}else
if ((arg1->_type == tk_IntData) && (arg2->_type == tk_FloatData)){
float* intResult = malloc(sizeof(float));
*intResult = *(int*)arg1->_data + *(float*)arg2->_data;
tokenResult = CreateTokenFromValue(intResult, tk_FloatData);
}else
if ((arg1->_type == tk_FloatData) && (arg2->_type == tk_IntData)){
float* intResult = malloc(sizeof(float));
*intResult = *(float*)arg1->_data + *(int*)arg2->_data;
tokenResult = CreateTokenFromValue(intResult, tk_FloatData);
}
else
if ((arg1->_type == tk_FloatData) && (arg2->_type == tk_FloatData)){
float* intResult = malloc(sizeof(float));
*intResult = *(float*)arg1->_data + *(float*)arg2->_data;
tokenResult = CreateTokenFromValue(intResult, tk_FloatData);
}
return tokenResult;
}
我对 -、*、/具有几乎相同的功能。我可能需要创造更多。
问题是: 我如何创建一个通用函数来支持所有简单操作,例如 +-*/? 我不想将此函数放在宏中,然后通过替换数学操作数将其复制 4 次。 有什么方法可以简化 void 指针的数据类型检查和转换?
有什么方法可以让这段代码变得更好?
假设:我没有任何非数字数据类型(例如字符串)
谢谢
太好了,非常感谢这些回复,我明白你所说的函数指针是什么意思了。 我将考虑并使用其中一种方法。谢谢
最佳答案
简答: c 根本不提供任何语法帮助。
好消息:您可以通过使用函数指针在 c 语言中支持多态性。 Stack Overflow 上已经有许多解释如何 的问题。稍后我将编辑一两个链接...
不喜欢我为这个用途找到的答案,所以这里是。
对于每个操作,编写一组采用所有合法类型组合的函数。每个人只做一种组合,所以很容易。然后像这样构造一个函数指针表
typedef Token* (*mathfuncptr)(void *, void *);
Token* _Add_IntInt(void *, void *);
Token* _Add_IntFloat(void *, void *);
Token* _Add_FloatInt(void *, void *);
/* ... */
mathfuncptr Add_table[AddTypeCount][AddTypeCount] = {
{_Add_IntInt, _Add_IntFloat},
{_Add_FloatInt, _Add_FloatFloat}
};
mathfuncptr Mul_table[MultTypeCount][MultTypeCount] = { /* ... */
现在您的通用添加函数确定它具有的两种类型,并通过索引到表中来调用正确的函数。
关于c - 使用指向数值数据的 void* 指针的算术运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2322277/