C中压栈出栈操作
Push pop stack operation in C
我试图通过将 pop 中的值存储在数组中来进行堆栈推送弹出操作。我对这段代码有几个问题。
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;
}
这里你又犯了一些错误。在你创建新线程之前
相似内容,一贴。
在您的代码中,您也从不检查 malloc
是否失败。这样做总是更好。为简单起见,我在建议中省略了这些检查。
1。
你为什么在 makeEmpty
中做 S1[0].top=-1;
? create
已经这样做了,并且以这种方式编写(而不是 S1->top = -1
)会使代码难以解释,因为这可能意味着您将 create
的结果视为 Stack
s。没错,这让我们更难理解你的意图。
Stack makeEmpty(void)
{
Stack S1=create(100);
return S1;
}
够了。
2。
在 push
和 pop
中,您必须首先检查操作是否有效。那
意思是:
- for
push
:检查您是否还有 space 来执行操作
- for
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);
3。
你想要 deleteStack
做什么:重置堆栈或释放内存?你
正在以一种糟糕的方式混合它们。
如果你想重置(意思是一次弹出所有元素),那么你有
要做的是设置top = -1
。您不必释放 array
。如果你这样做,那么你
需要再次为 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 引自评论:
Don't hide levels of pointer indirection behind typedef
是的,这也使代码难以阅读。在我的建议中我没有改变它,但我肯定会改变
typedef struct stack Stack;
并在每个以 Stack S
作为参数的函数中将其更改为 Stack *S
。 (另请参阅 Is it a good idea to typedef pointers — 简短的回答是 'No'。)
我试图通过将 pop 中的值存储在数组中来进行堆栈推送弹出操作。我对这段代码有几个问题。
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;
}
这里你又犯了一些错误。在你创建新线程之前 相似内容,一贴。
在您的代码中,您也从不检查 malloc
是否失败。这样做总是更好。为简单起见,我在建议中省略了这些检查。
1。
你为什么在 makeEmpty
中做 S1[0].top=-1;
? create
已经这样做了,并且以这种方式编写(而不是 S1->top = -1
)会使代码难以解释,因为这可能意味着您将 create
的结果视为 Stack
s。没错,这让我们更难理解你的意图。
Stack makeEmpty(void)
{
Stack S1=create(100);
return S1;
}
够了。
2。
在 push
和 pop
中,您必须首先检查操作是否有效。那
意思是:
- for
push
:检查您是否还有 space 来执行操作 - for
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);
3。
你想要 deleteStack
做什么:重置堆栈或释放内存?你
正在以一种糟糕的方式混合它们。
如果你想重置(意思是一次弹出所有元素),那么你有
要做的是设置top = -1
。您不必释放 array
。如果你这样做,那么你
需要再次为 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 引自评论:
Don't hide levels of pointer indirection behind
typedef
是的,这也使代码难以阅读。在我的建议中我没有改变它,但我肯定会改变
typedef struct stack Stack;
并在每个以 Stack S
作为参数的函数中将其更改为 Stack *S
。 (另请参阅 Is it a good idea to typedef pointers — 简短的回答是 'No'。)