我试图编写一个简单的后缀计算器,它读取行并使用堆栈执行计算。我想知道是否有人可以检查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/

10-12 16:14