关于C#:如何打印此堆栈中的值?

How can I print the value in this stackT?

我找到了一些代码来实现堆栈的C实现,并决定使用它。但是,有几个typedef,我很难在stackt(真正的char数组)中打印值。下面是代码。我做错什么了?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#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.
"
);
        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.
"
);
        exit(1);
    }
    stackP->contents[++stackP->top] = element;
}

stackElementT StackPop(stackT *stackP) {
    if(StackIsEmpty(stackP)) {
        fprintf(stderr,"Can't pop element: stack is empty.
"
);
        exit(1);
    }
    return stackP->contents[stackP->top--];
}

void StackDisplay(stackT *stackP) {
    if(StackIsEmpty(stackP)) {
        fprintf(stderr,"Can't display: stack is empty.
"
);
        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
"
, 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
"
, postfix(expr, i));
}


编译器(MacOS X 10.6.7上的GCC 4.2.1)告诉我:

1
2
3
4
5
$ 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()语句,就在你说你有问题的地方。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void StackDisplay(stackT *stackP)
{
    if(StackIsEmpty(stackP)) {
        fprintf(stderr,"Can't display: stack is empty.
"
);
        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]。使用该修复程序,程序"运行"但生成:

1
Can't pop element: stack is empty.

这是你现在要解决的问题。

(噢,我还修复了main()中的for循环后的迷路半结肠,正如在注释中诊断的那样。)

循环应该写为strlen(expr)(然后您需要#include )。实际上,主程序的主体简化为:

1
2
3
char* expr ="1 2 3 + * 3 2 1 - + *";
printf("%d
"
, postfix(expr, strlen(expr)));

您通常应该将top索引到下一个要使用的位置,因此初始值通常是0,而不是-1

不要学习数字的ASCII码-忘记你曾经学过的。

1
    if ((expr[i] >= 48) && (expr[i] <= 57)) {

你应该写:

1
    if ((expr[i] >= '0') && (expr[i] <= '9')) {

或者,更好(但你也必须这样做):

1
    if (isdigit(expr[i])) {

类似的注释适用于开关:

1
2
3
4
5
6
        switch (expr[i]) {
            case 43: {
                temp = StackPop(&stack);
                StackPush(&stack, StackPop(&stack)+temp);
            }
                break;

我不确定缩进背后的逻辑,但是43应该写为'+',45应该写为'-',47应该写为'/',42应该写为as'*'

这会产生:

1
2
3
4
5
6
7
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

如果您按如下所示修改了号码推送代码:

1
2
3
printf("Is a number! Pushed %d
"
, expr[i] - '0');
StackPush(&stack, expr[i] - '0');

然后你会得到:

1
2
3
4
5
6
7
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

再加上一些仪器,沿着以下路线:

1
2
3
4
temp = StackPop(&stack);
printf("Sub: result %d
"
, temp);
StackPush(&stack, temp);

每次操作后,结果是:

1
2
3
4
5
6
7
8
9
10
11
12
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

你很亲密。