对于大学作业的一个组件,我们必须实现一个堆栈,我认为我已经做得足够好了,它可以正常工作。当我自己测试堆栈时,它似乎工作正常,但是当我将它用作我的解决方案的一部分时,它的行为不同,我不知道为什么。有人可以指出我的错误吗?谢谢。
编辑:我能感觉到很多“它的行为有何不同?” 评论正在路上,所以这就是我注意到的。在运行 的测试堆栈部分时main
,所有操作都执行并打印得非常好,但是当我运行的第二部分main
并注释掉测试部分时,当我试图推入堆栈时程序崩溃 - 某事以前没有失败。
主程序
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct stackNode {
char data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
typedef enum {
false, true
} t_bool;
void* emalloc(size_t s) {
void* p = malloc(s);
if (NULL == p) {
fprintf(stderr, "Memory allocation failed.\n");
exit(EXIT_FAILURE);
}
return p;
}
void print_array(char* array, size_t n){
int i;
printf("[");
for(i = 0; i < n - 1; i++){
printf("%c, ", array[i]);
}
printf("%c]\n", array[i]);
}
// Determine if c is an operator.
int isOperator(char c) {
char ops [6] = {'+', '-', '*', '/', '%', '^'};
int i;
for (i = 0; i < 6; i++)
if (ops[i] == c) return true;
return false;
}
int op_priority(char c) {
if (c == '+' || c == '-') return 0;
else if (c == '*' || c == '/') return 1;
else if (c == '^' || c == '%') return 2;
return -1;
}
// Determine if the precedence of operator1 is less than, equal to, or greater than
// the precedence of operator2. The function returns -1, 0 and 1, respectively.
int precedence(char op1, char op2) {
int op1_p = op_priority(op1);
int op2_p = op_priority(op2);
if (op1_p < op2_p) return -1;
else if (op1_p > op2_p) return 1;
else return 0;
}
// Push a value on the stack.
void push(StackNodePtr *topPtr, char value) {
StackNodePtr temp = (StackNodePtr) emalloc(sizeof (StackNode));
temp->data = value;
temp->nextPtr = *topPtr;
*topPtr = temp;
}
// Pop a value off the stack.
char pop(StackNodePtr *topPtr) {
StackNodePtr t = *topPtr;
if (NULL != *topPtr) {
char c = t->data;
*topPtr = t->nextPtr;
free(t);
return c;
} else {
printf("Stack is empty.\n");
return '\0';
}
}
// Return the top value of the stack without popping the stack.
char peek(StackNodePtr topPtr) {
if (NULL != topPtr) {
return topPtr->data;
} else {
printf("Stack is empty.\n");
}
}
// Determine if the stack is empty.
int isEmpty(StackNodePtr topPtr) {
if (NULL == topPtr) return true;
return false;
}
// Prints the stack
void printStack(StackNodePtr topPtr) {
if (!isEmpty(topPtr)){
StackNodePtr t = topPtr;
while (NULL != t) {
printf("%c\t", t->data);
t = t->nextPtr;
}
printf("NULL\n");
} else {
printf("Stack is empty.\n");
}
}
// Convert the infix expression to postfix notation.
void convertToPostfix(char infix [], char postfix [], int expression_length) {
printf("At top of cnvToPostfix\n");
int infix_count = 0;
int postfix_count = 0;
////////////////////////////////////////////
StackNodePtr *stack;
push(stack, '(');
printStack(*stack);
////////////////////////////////////////////
infix[expression_length] = ')';
while (isEmpty(*stack)) {
char current = infix[infix_count++];
if (isdigit(current)) {
postfix[postfix_count++] = current;
} else if (current == '(') {
push(stack, current);
} else if (isOperator(current)) {
while (true) {
char top = peek(*stack);
if (isOperator(top) && precedence(current, top) >= 0) {
postfix[postfix_count++] = pop(stack);
} else {
break;
}
}
push(stack, current);
}
else if (current == ')') {
while (true) {
char top = peek(*stack);
if (top == '(') {
pop(stack);
break;
} else {
postfix[postfix_count++] = pop(stack);
}
}
}
}
}
int main() {
printf("Testing stack\n");
printf("Pushing 1, 2, and 3 onto stack, peeking and popping.\n");
StackNodePtr *stack;
push(stack, '1');
push(stack, '2');
push(stack, '3');
printf("Printing stack\n\n");
printStack(*stack);
printf("Peek: %c\n", peek(*stack));
printf("Pop: %c\n", pop(stack));
printf("Printing stack\n");
printStack(*stack);
/*
printf("Enter the infix expression.\n");
char c;
char infix [1024];
int count = 0;
while ((scanf("%c", &c)) == 1) {
if ((int) c == 10) break;
infix[count++] = c;
}
printf("The original infix expression is:\n");
print_array(infix, count);
char postfix [count];
convertToPostfix(infix, postfix, count);
printf("The expression in postfix notation is:\n");
print_array(postfix, count);
*/
return 0;
}