我找到了一些代码来实现堆栈的C实现,并决定使用它。但是,有几个typedef,我很难在stackT中打印值(实际上是一个char数组)。下面是代码。我做错了什么?
#include <stdio.h> #include <stdlib.h> typedef char stackElementT; typedef struct { stackElementT *contents; int maxSize; int top; } stackT; void StackInit(stackT *stackP, int maxSize) { stackElementT *newContents; newContents = (stackElementT *)malloc(sizeof(stackElementT)*maxSize); if (newContents == NULL) { fprintf(stderr, "Not enough memory.\n"); exit(1); } stackP->contents = newContents; stackP->maxSize = maxSize; stackP->top = -1; //empty... } void StackDestroy(stackT *stackP) { free(stackP->contents); stackP->contents = NULL; stackP->maxSize = 0; stackP->top = -1; //empty } int StackIsEmpty(stackT *stackP) { return stackP->top < 0; } int StackIsFull(stackT *stackP) { return stackP->top >= stackP->maxSize-1; } void StackPush(stackT *stackP, stackElementT element) { if(StackIsFull(stackP)) { fprintf(stderr, "Can't push element: stack is full.\n"); exit(1); } stackP->contents[++stackP->top] = element; } stackElementT StackPop(stackT *stackP) { if(StackIsEmpty(stackP)) { fprintf(stderr, "Can't pop element: stack is empty.\n"); exit(1); } return stackP->contents[stackP->top--]; } void StackDisplay(stackT *stackP) { if(StackIsEmpty(stackP)) { fprintf(stderr, "Can't display: stack is empty.\n"); exit(1); } int i; printf("[ "); for (i = 0; i < stackP->top; i++) { printf("%c, ", stackP[i]); //the problem occurs HERE } printf("%c ]", stackP[stackP->top]); } int postfix(char* expr, int length) { int i; stackT stack; StackInit(&stack, 1000); int temp; for (i = 0; i < length; i++) { if ((expr[i] >= 48) && (expr[i] <= 57)) { printf("Is a number! Pushed %d\n", expr[i]); StackPush(&stack, expr[i]); } else { switch (expr[i]) { case 43: { temp = StackPop(&stack); StackPush(&stack, StackPop(&stack)+temp); } break; case 45: { temp = StackPop(&stack); StackPush(&stack, StackPop(&stack)-temp); } break; case 47: { temp = StackPop(&stack); StackPush(&stack, StackPop(&stack)/temp); } break; case 42: { temp = StackPop(&stack); StackPush(&stack, StackPop(&stack)*temp); } break; default: break; } } } return StackPop(&stack); } int main() { int i; char* expr = "1 2 3 + * 3 2 1 - + *"; for(i = 0; expr[i] != '\0'; i++) ; printf("%d\n", postfix(expr, i)); }
答案 0 :(得分:7)
编译器(Mac OS X 10.6.7上的GCC 4.2.1)告诉我:
$ cc -O -std=c99 -Wall -Wextra st.c -o st
st.c: In function ‘StackDisplay’:
st.c:72: warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘stackT’
st.c:74: warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘stackT’
$
在我的代码版本中,这两行是printf()
中的StackDisplay()
语句,
你说你有问题的地方。
void StackDisplay(stackT *stackP)
{
if(StackIsEmpty(stackP)) {
fprintf(stderr, "Can't display: stack is empty.\n");
exit(1);
}
int i;
printf("[ ");
for (i = 0; i < stackP->top; i++) {
printf("%c, ", stackP[i]); //the problem occurs HERE
}
printf("%c ]", stackP[stackP->top]);
}
你可能想要stackP->contents[i]
。通过该修复,程序“运行”但产生:
Can't pop element: stack is empty.
现在,这是你要解决的问题。
(哦,我还在评论中诊断的 for
main()
循环之后修复了杂散分号。)
循环应写为strlen(expr)
(然后你需要#include <string.h>
)。实际上,主程序的主体简化为:
char* expr = "1 2 3 + * 3 2 1 - + *";
printf("%d\n", postfix(expr, strlen(expr)));
您通常应将top
索引到下一个要使用的位置,因此初始值通常为0
而不是-1
。
不要学习数字的ASCII代码 - 忘了你曾经做过。
if ((expr[i] >= 48) && (expr[i] <= 57)) {
你应该写:
if ((expr[i] >= '0') && (expr[i] <= '9')) {
或更好(但你也必须#include <ctype.h>
):
if (isdigit(expr[i])) {
类似的评论适用于交换机:
switch (expr[i]) {
case 43: {
temp = StackPop(&stack);
StackPush(&stack, StackPop(&stack)+temp);
}
break;
我不确定缩进背后的逻辑,但43应写为'+'
,45为'-'
,47为'/'
,42为{{1} }}
这会产生:
'*'
如果您按照所示修正数字推送代码:
Is a number! Pushed 49
Is a number! Pushed 50
Is a number! Pushed 51
Is a number! Pushed 51
Is a number! Pushed 50
Is a number! Pushed 49
68
然后你得到:
printf("Is a number! Pushed %d\n", expr[i] - '0');
StackPush(&stack, expr[i] - '0');
使用更多的仪器,按照以下方式:
Is a number! Pushed 1
Is a number! Pushed 2
Is a number! Pushed 3
Is a number! Pushed 3
Is a number! Pushed 2
Is a number! Pushed 1
20
每次操作后,结果为:
temp = StackPop(&stack);
printf("Sub: result %d\n", temp);
StackPush(&stack, temp);
你很亲密。