有人可以告诉我如何从堆栈顶部拉出两个元素,而不是遍历整个堆栈:/
#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
}
}
}
答案 0 :(得分:2)
首先,我认为你的意思是从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 值。
接下来,以下情况似乎不对:
/*
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 (无论你真正想要的是什么)
use)作为函数的返回类型。
在if
语句的条件部分中,您需要包围运算符 char 值
在这样的单引号之间:if (*token == '+')
等等
如果if
语句,大括号出现问题。在真实的部分,你并不是真的
因为你有一个要执行的语句,所以需要打开一个大括号(你忘了关闭)。
请考虑删除{
或在其他部分之前将其关闭。
您在char &token
条件部分中声明if
几次。我想你真的只是想要
像上面第二个子弹中的例子一样使用它。同样,当你时,你要声明int a
两次
应该只在else部分说a = *token;
。顺便说一句,如果你真的要宣布一个
char引用(在函数参数列表中),您应该已经标记了这个问题
作为 C ++ 。然后你会分别做a = token
。
编辑:当我写这篇文章时,你的问题的评论似乎解释了更多关于
&token
和*token
之间的差异。
实际上,else {}
前面提到的语句和后面的switch语句
即使令牌不是运营商,也会被执行。
您正在为 StackElement 动态分配内存,但之后却从不执行某些操作
指针temp
,当它在范围内时。函数返回后,您无法引用
再次访问该内存,直到程序终止才会释放它。
这些是对您的代码的一些快速(或者我的第一个答案的想法)观察。我相信我们的社区将能够提供更多帮助,并指出代码中的任何其他错误/改进(也可能是我的)。祝你实施计算器好运! : - )