我试图通过在数组中存储pop中的值来进行堆栈推送弹出操作。我对这段代码有几个问题
1.初始化部分是否运行良好?在编译时,似乎没有问题,但我仍然很好奇
2.删除部分是否也能正常工作?虽然,我输入了!
,但它似乎并不属于else if(strcmp (str[i], "!")==0)
部分。
3.如何在弹出操作后存储值?我想将它存储为数组格式但是当我将它们存储在数组中后打印出来时,会发生运行时错误
以下是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct stack *Stack;
struct stack {
char *array;
int size;
int top;
};//making stack
Stack create(int c);
Stack makeEmpty(void);//initialization
int isEmpty(Stack S)
{
if(S->top==-1)
return 0;
else
return 1;
};
void push(char X, Stack S)
{
S->array[++S->top]=X;
};
char pop(Stack S)
{
return S->array[S->top--];
};
void deleteStack(Stack S)
{
while (S->top>=0)
{
free(S->array[S->top]);
S->top--;
}
};
int main (void)
{
Stack S1=makeEmpty();
char input[100], result[30], result1;
char *word;
int cnt=0,cnt2=0, temp=0, k=0, i,j,l;
word=strtok(input, " ");
char *str[20];
while(1){
if(fgets(input,100,stdin)){
word=strtok(input, " ");//get input and tokenize
cnt=0;
while (word!=NULL)
{
str[cnt]=strdup(word);
cnt++;
word=strtok(NULL," ");
}
}
for (i=0; i<cnt; i++)
{
if (strcmp(str[i],"(")==0 && (isEmpty(S1)==0))
{
push(str[i],S1);
l++;
}
else if(strcmp(str[i],")")==0)
{
temp++;
for(j=0; j<cnt2; j++)
{
char result1=pop(S1);
result[k] =result1;
printf("%s ", result[k]);//This the place where I got runtime error
k++;
}
pop(S1);
cnt2=0;
}
else if(strcmp (str[i], "!")==0)
{
printf("in\n");
deleteStack(S1);
return 0;
}
else
{
if (isEmpty(S1)==1)
{
if (l!=0)
{
push(str[i],S1);
if (strcmp(str[i],"(")!=0)
{
cnt2++;
}
}
}
}
}
}
return 0;
}
Stack create(int c)
{
Stack S=(Stack)malloc(sizeof(struct stack));
S->size=c;
S->top=-1;
S->array=(char *)malloc(sizeof(char)*c);
return S;
}
Stack makeEmpty(void)
{
Stack S1=create(100);
S1[0].top=-1;
return S1;
}
答案 0 :(得分:2)
这里你又有些不对劲了。在使用之前创建新线程之前 类似的内容,坚持一个线程。
在您的代码中,您也永远不会检查malloc
是否失败。这样做总是更好。为简单起见,我在我的建议中省略了这些检查。
1。
为什么在S1[0].top=-1;
中makeEmpty
进行操作? create
已经这样做并且以这种方式编写(而不是S1->top = -1
)会使代码难以解释,因为这可能意味着您将create
的结果视为{的数组{1}}秒。这没有错,我们更难以解释你的意图。
Stack
就够了。
2。
在Stack makeEmpty(void)
{
Stack S1=create(100);
return S1;
}
和push
中,您必须首先检查操作是否有效。那
的意思是:
pop
:检查您是否还有空间进行操作push
:检查堆栈中是否至少有一个元素。代码可以是:
pop
我更改了这些功能的签名,让用户知道 if
手术成功。否则你不知道,你最终得到了
未定义的值。在主要内容中,您还应更改int isFull(Stack S)
{
return (S->size - 1 == S->top);
}
int push(char X, Stack S)
{
if(isFull(S))
return 0;
S->array[++S->top]=X;
return 1;
}
int pop(Stack S, char *val)
{
if(isEmpty(S))
return 0;
*val = S->array[S->top--];
return 1;
}
来电:
pop
3。
你想要char el;
pop(S1, &el);
做什么:重置堆栈还是释放内存?您
正在以糟糕的方式混合它们。
如果你想重置(意思是一次弹出所有元素),那么你就拥有了
要做的是设置deleteStack
。您不必免费top = -1
。如果你这样做,那么你
需要再次为array
重新分配内存。
使用array
时,您只能传递free
相同的指针
你来自free
/ malloc
/ calloc
。在你的代码中,你传递了一个
8位整数作为指针地址并释放它,这将使你的
程序在100%的时间内崩溃。
realloc
如果你想释放内存
void deleteStack(Stack S)
{
S->top = -1;
}
但这也意味着您无法再访问堆栈了。请注意我 更改了函数的名称,使其更清晰。
如果您使用我的建议,则必须在void freeStack(Stack S)
{
free(S->array);
free(S);
}
中更改它们,
特别是main
s。
修改强>: Sebivor从评论中引用:
不要隐藏
后面指针间接的级别pop
是的,这也使代码难以阅读。在我的建议中我没有改变,但我肯定会改变
typedef
并且在每个以typedef struct stack Stack;
为参数的函数中将其更改为Stack S
。 (另见Is it a good idea to typedef pointers - 简答回答是'否'。)