【问题标题】:Calculator in C with Stack and Linked List带有堆栈和链表的 C 中的计算器
【发布时间】:2014-12-17 22:01:07
【问题描述】:

我正在尝试编写一个简单的后缀计算器来读取行并使用堆栈执行计算。我想知道是否有人可以检查结构和推送功能是否正确实现。我非常感谢任何我需要考虑的建议或线索。 我是信息学专业的学生,​​也是我最想在圣诞节前完成的第一个程序之一:)

谁能告诉我如何从栈顶取出两个元素而不是遍历整个栈:/

#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
        }
    }
}

【问题讨论】:

  • 这看起来像是一份工作:codereview.stackexchange.com
  • 什么是if ( char &amp;token == + ||char &amp;token== - char &amp;token == * )?这是 C 吗?
  • 我已经更正了一点。我想写一个“或”条件。此行应检查 Token 是 +、- 还是 * 标记。 ' if ( char &token == + ||char &token== - || char &token == * ) == 0 )'code'
  • @StarPilot:这并不完全是代码审查的主题。它必须已经在工作(OP 不确定它是否完整),我们无法帮助添加额外的实现(第二段)。
  • if 语句确实不正确,首先你不必命名类型,这从声明中已经知道。 2、如果你想和char '+'比较,你应该做== '+',否则调用+操作符。 3.如果你想比较地址token处的字符,你应该做*token而不是&token,&token返回token指针的地址,所以是adress的地址。

标签: c list stack calculator


【解决方案1】:

堆栈元素

首先,我认为您的意思是从 typedef 开始您对 StackElement 结构的定义,例如:

typedef struct StackElement {
    int data;
    struct StackElement *next;
} StackElement;

然后,作为 StackElement 结构类型成员的 next 指针指向 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;,但稍后为其分配了一个float值。

stack_top 指针

接下来,以下内容似乎有些不对劲:

    /*
   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 变量。考虑指定一个 intfloat (无论你真正想要 使用) 作为函数的返回类型。

  • if 语句的条件部分,您需要将operator char 值括起来 像这样的单引号之间:if (*token == '+')

  • if 语句中的花括号存在问题。在真实的部分,你真的不 需要打开一个大括号(您忘记关闭),因为您有一个要执行的语句。 考虑删除 { 或在 else 部分之前将其关闭。

  • 您在if 条件部分声明了几次char &amp;token。我想你真的只是想 像我在上面第二个项目符号上的示例一样使用它。同样,您声明 int a 两次,当您 应该只在 else 部分说a = *token;。顺便说一句,如果您真的要声明一个 char 参考(在函数参数列表上),你应该已经标记了这个问题 C++。然后你会分别做a = token。 编辑:当我写这篇文章时,对你的问题的评论出现在解释更多关于 &amp;token*token 之间的区别。

  • 事实上,有else {}前面提到的语句和后面的switch语句 即使 token 不是运算符也会实际执行。

  • 您正在为 StackElement 动态分配内存,但从不使用 该指针temp,当它在范围内时。函数返回后你没有办法引用 再次到那个内存,直到程序终止它才会被释放。

这只是故事的一部分......

这些是对您的代码的一些快速(或者这是我的第一个答案的想法)的观察。我相信我们的社区将能够提供更多帮助并指出您代码中的任何其他错误/改进(可能也是我的)。祝您使用计算器好运! :-)

【讨论】:

  • 非常感谢@Gregory Kyriazis ;) 它有效! ;)
猜你喜欢
  • 1970-01-01
  • 2015-09-15
  • 2011-05-04
  • 2012-10-25
  • 2011-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
相关资源
最近更新 更多