首页 文章

如何在此堆栈中打印值?

提问于
浏览
0

我找到了一些代码来实现堆栈的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));
}

1 回答

  • 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’
    $
    

    在我的代码版本中,这两行是 StackDisplay() 中的 printf() 语句,您说明您遇到问题 .

    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] . 使用该修复程序,程序'runs'但产生:

    Can't pop element: stack is empty.
    

    现在,这是你要解决的问题 .

    (哦,我还在main()中的for循环之后修复了迷路分号,如评论中所诊断的那样 . )

    循环应写为 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作为 '*' .


    这会产生:

    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);
    

    每次操作后,结果是:

    Is a number! Pushed 1
    Is a number! Pushed 2
    Is a number! Pushed 3
    Add: result 5
    Mul: result 5
    Is a number! Pushed 3
    Is a number! Pushed 2
    Is a number! Pushed 1
    Sub: result 1
    Add: result 4
    Mul: result 20
    20
    

    你很亲密

相关问题