C语言中的Push-pop堆栈操作
我试图通过在数组中存储来自pop的值来实现堆栈推送pop操作。我对这段代码有几个问题。C语言中的Push-pop堆栈操作,c,arrays,struct,strcmp,C,Arrays,Struct,Strcmp,我试图通过在数组中存储来自pop的值来实现堆栈推送pop操作。我对这段代码有几个问题。 1.初始化部分工作正常吗?编译时,似乎没有问题,但我还是很好奇。 2.删除部分也能正常工作吗?尽管如此,我还是输入了,似乎它不会转到else if(strcmp(str[i],“!”==0)部分。 3.如何在pop操作后存储值?我想将其存储为数组格式,但在数组中存储后打印时,出现运行时错误。 代码如下: #include <stdio.h> #include <stdlib.h> #i
1.初始化部分工作正常吗?编译时,似乎没有问题,但我还是很好奇。
2.删除部分也能正常工作吗?尽管如此,我还是输入了
代码>,似乎它不会转到else if(strcmp(str[i],“!”==0)
部分。
3.如何在pop操作后存储值?我想将其存储为数组格式,但在数组中存储后打印时,出现运行时错误。
代码如下:
#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;
}
#包括
#包括
#包括
类型定义结构堆栈*堆栈;
结构堆栈{
字符*数组;
整数大小;
int top;
};//制作堆栈
堆栈创建(intc);
堆栈makeEmpty(void)//初始化
int isEmpty(堆栈S)
{
如果(S->top==-1)
返回0;
其他的
返回1;
};
无效推送(字符X,堆栈S)
{
S->array[++S->top]=X;
};
char pop(堆栈S)
{
返回S->array[S->top--];
};
无效删除堆栈(堆栈S)
{
而(S->top>=0)
{
自由(S->数组[S->顶部];
S->顶部--;
}
};
内部主(空)
{
堆栈S1=makeEmpty();
字符输入[100],结果[30],结果1;
字符*字;
int cnt=0,cnt2=0,temp=0,k=0,i,j,l;
word=strtok(输入“”);
char*str[20];
而(1){
if(fgets(输入,100,标准输入)){
word=strtok(输入,“”;//获取输入并标记化
cnt=0;
while(word!=NULL)
{
str[cnt]=strdup(word);
cnt++;
word=strtok(空,“”);
}
}
对于(i=0;itop=-1;
S->array=(char*)malloc(sizeof(char)*c);
返回S;
}
堆栈makeEmpty(void)
{
堆栈S1=创建(100);
S1[0]。top=-1;
返回S1;
}
这里您又出现了一些问题。在使用创建新线程之前
类似的内容,坚持一个线程
在您的代码中,您也从不检查malloc是否失败。这样做总是更好。为简单起见,我在建议中省略了这些检查
一,。
为什么要执行S1[0]。top=-1;
中的makeEmpty
?create
已经这样做并以那种方式写入(而不是S1->top=-1
)使代码难以解释,因为这可能意味着您正在将create
的结果视为堆栈的数组。这没有错,这使我们更难解释您的意图
Stack makeEmpty(void)
{
Stack S1=create(100);
return S1;
}
够了
二,。
在push
和pop
中,您必须首先检查操作是否有效
指:
- 对于
推送
:检查您是否仍有空间进行操作
- 对于
pop
:检查堆栈上是否至少有一个元素
代码可以是:
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
调用:
char el;
pop(S1, &el);
三,。
您希望deleteStack
做什么:重置堆栈或释放内存?您可以
把它们混在一起很糟糕
如果您想要重置(意味着一次弹出所有元素),那么您所拥有的
要做的是设置top=-1
。您不必释放array
。如果这样做,那么
需要再次为数组重新分配内存
使用free
时,只能将同一指针传递给free
您已经从malloc
/calloc
/realloc
获得了。在您的代码中,您正在传递一个
8位整数作为指针地址并释放它,这将使
程序崩溃100%的时间
void deleteStack(Stack S)
{
S->top = -1;
}
如果你想释放内存
void freeStack(Stack S)
{
free(S->array);
free(S);
}
但是这也意味着您不能再访问堆栈了
更改了函数的名称以使其意图更加明确
如果您使用我的建议,您还必须在main
中更改它们,
特别是pop
s
编辑:
Sebivor对评论的引用:
不要在typedef
是的,这也使得代码很难阅读。在我的建议中,我没有改变这一点,但我肯定会改变
typedef struct stack Stack;
在每一个有堆栈S
作为参数的函数中,将其更改为堆栈*S
(另请参见-简短的回答是“否”)您的前两个问题太笼统了:“好吗?”定义,首先?此外,你在一个问题中问了3个不同的问题。只有最后一个问题有一些优点,但如果你把你的代码和问题集中在这一点上,那就更好了:将你的代码限制在产生错误的最小示例中,并让我们知道你已经做了什么来调试你的问题al reading:@Sebivor正如你所知,pipe
不是标准的C,而是POSIX
。此外,每次使用操作系统来获取一个简单的堆栈听上去都是浪费资源。@Sebivor:我相信pipe会给出FIFO(先进先出)规则,而不是堆栈(后进先出)规程。mkfifo()
用于创建“命名管道”是有原因的。