Как я могу напечатать значение в этом стеке? - PullRequest
0 голосов
/ 08 июня 2011

Я нашел некоторый код для реализации стеков на 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 голосов
/ 08 июня 2011

Компилятор (GCC 4.2.1 на MacOS X 10.6.7) говорит мне:

$ 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 как '*'.


Это создает:

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

Вы были близки.

...