我即将在c中完成一个类似于简单计算器的项目,我想知道如何允许用户在程序运行期间创建变量,这个变量可能是数字或复数甚至是矩阵或 一种方法是将变量的类型,其名称及其大小和值存储在临时文本文件中,并在需要时检索它,是否有更好的方法。我希望如果我能在运行期间在c
中声明实数变量答案 0 :(得分:0)
你不能在C语言中在运行时声明新的变量。
根据您的需要,您可以为要支持的每种类型创建结构列表。然后,每个结构包含变量的名称及其值。声明变量将在列表中添加新结构。
答案 1 :(得分:0)
我假设您正在考虑与您的交互计算器,可能看起来像这样:
> myCalc
mc> x=5
mc> 5
mc> 3*x
mc> 15
mc> quit
>
其中myCalc
是程序的名称,mc>
提示符显示与计算器的交互,其中use使用输入语句,计算器显示语句的结果。
现在,考虑第一个语句x=5
,我们需要解析它并根据您使用的语法确定它是否有效。假设它是,那么您需要评估该语句,以供讨论
抽象语法树(AST)ASMT(x,VAL(5))
。 ASMT和VAL是名义运营商。
现在,我将此视为将x的新绑定添加到当前环境中。确切地说,这种环境看起来取决于你愿意允许的内容,所以现在假设你只是允许变量赋值。这里有一个简单的关联数组,其中键是变量名,数据是值。
现在考虑下一个语句3*x
,在解析后我们可以假设表达式的AST是TIMES(3, ID(x))
。现在对此进行评估,或者解释器首先需要处理ID(x)
部分,该部分将在环境中查找x
的值,即5。
在上述之后,AST看起来像TIMES(3,5)
,它将被直接评估为15。
N.B。我对AST如何表示以及如何由解释器进行评估感到相当宽松。我试图说明要做什么,而不是完整的低级实现细节。
希望这会有所帮助(有点), Ť
答案 2 :(得分:0)
好的,您将需要三个基本模块:
N.B。我没有时间真正编译这些例子,希望我没有犯太多错误。
让我们从环境开始,这是我们需要的(或者至少我要实现的)。首先是我将用于环境的设计考虑因素:
现在,让我们定义以下结构:
typedef struct st
{
char* tokenName;
int type;
union
{
int iVal;
float fVal;
} val;
} tableEntry, * ptableEntry;
tableEntry symbolTable[300];
现在有些功能:
一个。 init(tableEntry *) - 此函数初始化环境,即将符号表中的所有值设置为某个预定义的空状态。
湾addValue(tableEntry *,name,value) - 此函数获取指向环境的指针并向环境添加新条目。
℃。 int lookupValue(tableEntry *,name) - 此函数获取指向环境的指针,并查看是否已在其中定义了令牌名称。我们已经看到了一个问题,我们允许使用整数和浮点数,但是想要一个查找函数,所以我们可能需要某种变体类型或者想出一些返回不同类型的方法。
d。 updateValue(tableEntry *,name,value) - 此函数获取指向环境的指针并更新现有值。这引发了一个未解决的规范,如果找不到令牌,updateValue会怎么做?就个人而言,我只想添加价值,但这取决于你作为计算器的设计者做什么。
这应该是环境的开始。
现在让我们转向解释器。为此,假设解析器以前缀形式发出抽象语法树。例如:
语句x = 3将作为= x 3
发出
语句z = 4 + 5将作为= z + 4 5
好的,这里的诀窍是我们不会真正发出3
,而是一个包含有关传递内容的更多信息的令牌。
令牌的可能实现可能是:
typedef struct tok
{
int tokType;
char* tokVal;
} token, * ptoken;
还可以使用以下枚举:
enum {EMPTY=0, ID, VAL, EQ, PLUS, SUB, MULT, DIV, LPAREN, RPAREN};
所以,简而言之= x 3
,实际上就是以下内容
结构:
{EQ, null} {ID, "x"} {VAL, "3"}
好的,所以伪代码中的解释器看起来像(假设上面的代码作为列表呈现给解释器)。
while list not empty
token <-- head(list) /* this returns the first token as well as removing it from the list */
switch (token.tokType)
{
....
case EQ: /* handling assignment */
token <--- head(list)
name = token.name
token <--- head(list)
val = atoi(token.tokVal)
addValue(env*, name, val);
break;
case ID:
name = token.name
val = lookupValue(env*, name)
....
}
请注意,上述代码的实际格式很可能需要修改以处理其他结构,这只是一个名义上的例子!
现在轮到你了 - 试一下,向我们展示你的想法。
后来 吨。