我试图编写一个简单的后缀计算器,它读取行并使用堆栈执行计算。我想知道是否有人可以检查I s struct和push函数是否正确实现。我会非常乐意得到任何建议或线索,我需要考虑的。
我是一名信息学的学生,也是我第一个想在圣诞节前完成的课程之一:)
有人能告诉我如何从堆栈的顶部拉出两个元素而不遍历整个堆栈吗/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
#include <string.h>
#include <math.h> // Definnes special Float - NAN ("Not A Number")
struct StackElement{
int data;
struct element *next;
}StackElement;
/*
Typ stack_top is pointer to the StackElement
*/
typedef struct StackElement* stack_top{
StackElement* first;
}stack_top;
/*
starc
Lay Element on Stack
If *stacktop points to NULL, there is no element in the Stack
*/
void stack_push(stack_top *stacktop, float value)
{
if(stacktop->first == NULL){
StackElement->data = value;
StackElement->next= NULL;
stack_top->first= *StackElement;
}
else{
StackElement->next = stack_top-> first;
stack_top->first= *StackElement; // New first element
StackElement->data= value;
}
/*
Take one element from the stack
If Stack is empty than set *stacktop = NULL
, give float NAN back
*/
float stack_pop(stack_top *stacktop)
{
if(&stacktop==NULL){
printf("Stack ist leer \n")
}
// Hier Code einfügen
return NAN;
}
/*
Identyfy Token. Difference few cases:
- Token is a nummber : lay it on the Stack.
- Token is an Operator (+, -, *):
1. Take the two elements from the top of the Stack.
2. Use the operator.
3. Lay the result back on the top of the stack.
Implementiere hier die Rechenoperationen (+, -, *) und lege das
Ergebnis zurück auf den Stack. Beachte, dass du mit Floatingpointwerten
arbeitest, z.B. auch negative Kommazahlen.
*/
void process(stack_top *stacktop, char* token)
{ int a, operand1, operand2;
assert(token != NULL);
StackElement* temp = malloc(sizeof(StackElement));
if ( char &token == + ||char &token== - || char &token == * ) == 0 )
{
stack_push(stacktop, token)
else{}
int a= &token;
switch(a)
{
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
}
return result;
}
}
const int MAX_LINE_LENGTH=1024;
/*
main() reads the Input line by line and divides it single separate Tokens (linked list).
Diese Funktion muss nicht geändert werden.
*/
int main(int argc, char** args)
{
stack_top stacktop = NULL;
char line[MAX_LINE_LENGTH]; // Input line
char* token; // Pointer the current token;
while ( fgets(line, MAX_LINE_LENGTH, stdin) ) {
token = strtok(line, " ");
while (token != NULL) {
process(&stacktop, token); // perform Stackoperationen
token = strtok(NULL, " "); // Read new Token
}
float result = stack_pop(&stacktop); // Take Last result from Stack .
if (stacktop != NULL) { // Mehr Operanden als benötigt angegeben. Fehler.
while (stacktop != NULL) {
stack_pop(&stacktop); //Clean Stack
}
printf("Error\n");
} else if (result != result) { // result ist NAN: Berechnung fehlgeschlagen (z.b. zu wenig Operanden)
printf("Error\n");
} else {
printf("%4.3f\n", result); // Gib Resultat aus
}
}
}
最佳答案
斯塔克元素
首先,我想您应该从typedef开始定义StackElement结构,比如:
typedef struct StackElement {
int data;
struct StackElement *next;
} StackElement;
然后,下一个指针(StackElement结构类型的成员)指向StackElement本身:这个单独链接列表中的下一个节点。顺便说一句,这个自引用声明正是不能省略结构的标记名并像这样简化的原因:
typedef struct { /* Unnamed structure here, no "StackElement" this time */
int data;
struct StackElement *next; /* Error here, StackElement tag name was never defined */
} StackElement;
顺便说一下,我们可以看到这里选择了
int data;
,但稍后会给它分配一个浮点值。堆栈顶端指针
接下来,以下几点似乎不对:
/*
Typ stack_top is pointer to the StackElement
*/
typedef struct StackElement* stack_top{
StackElement* first;
}stack_top;
我相信您打算做的是声明一个指向StackElement的指针,特别是一个将始终指向堆栈顶部的指针,这也是代码上方的注释所支持的。在这种情况下,由于StackElement类型已经声明,您只需执行以下操作:
StackElement *stack_top; /* ... or StackElement *first; */
如果您真的想要StackElement*类型的另一个别名,可以执行以下操作:
typedef StackElement*stackPtr;
然后声明实际变量:
stackPtr stack_top;
过程函数
流程功能存在一些明显的问题:
它是一个void函数,返回未声明的
result
变量。考虑指定一个int或float(无论您真正想要使用)作为函数的返回类型。
在
if
语句的条件部分中,需要将运算符char值括起来在这样的单引号之间:
if (*token == '+')
,等等。if
语句中的花括号有问题。事实上,你不是真的需要打开一个大括号(忘记关闭),因为只有一条语句要执行。
考虑删除
{
或在其他部分之前关闭它。您在
char &token
条件部分声明了if
几次。我想你真的只是想就像我在上面第二个子弹上的例子一样。同样,当您
应该只在else部分说
int a
。顺便说一下,如果你真的想申报字符引用(在函数参数列表中),您可能已经标记了这个问题
作为C++。然后分别执行
a = *token;
。编辑:当我写这篇文章的时候,一个关于你的问题的评论出现了,解释了
a = token
和&token
之间的差异。事实上,前面提到的语句和后面的switch语句
即使令牌不是运算符,也实际执行。
您正在为StackElement动态分配内存,但从未使用
当指针在作用域中时,
*token
。函数返回后,您无法引用再次释放到内存,直到程序终止。
这只是故事的一部分。。。
这些是对你的代码的快速观察(或者这是我第一次回答的想法)。我相信我们的社区将能够提供更多帮助,并指出代码中的任何其他错误/改进(可能还有我的)。祝你计算机的实现好运!:-)
关于c - C中具有堆栈和链接列表的计算器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27535656/