[英]Simple stack program in C
我在OS類中,我必須編寫一個簡單的堆棧程序(main函數只是確定用戶要求你做什么)。 如果這不是必須在C中,我會在很久以前完成這個,但因為我不擅長C編碼,它有“一個錯誤”......到目前為止的錯誤是它只是繼續“流行“相同的價值。 (它實際上並沒有彈出任何東西)。 我認為這是因為我不明白結構和指針是如何工作的。 或者這是一個不那么明顯的編碼錯誤?
#include <stdio.h>
struct node {
int data;
struct node *next;
struct node *prev;
} first;
void push(int);
void pop();
int main(void)
{
int command = 0;
while (command != 3)
{
printf("Enter your choice:\n1) Push integer\n2) Pop Integer\n3) Quit.\n");
scanf("%d",&command);
if (command == 1)
{
// push
int num;
scanf("%d",&num);
push(num);
}
else
{
if (command == 2)
{
pop();
}
else
{
if (command != 3)
{
printf("Command not understood.\n");
}
}
}
}
return 0;
}
void push (int x)
{
struct node newNode;
newNode.data = x;
newNode.prev = NULL;
newNode.next = &first;
first = newNode;
printf("%d was pushed onto the stack.\n", first.data);
}
void pop()
{
if (first.data == '\0')
{
printf("Error: Stack Empty.\n");
return;
}
printf("%d was popped off the stack.\n", first.data);
first = *(first.next);
first.prev = NULL;
}
首先應該是一個指針。 首先將其更改為struct node * ;
在main initialize first = NULL ;
改變你的推/彈操作如下,
void push (int x)
{
struct node *newNode;// It should be a pointer
newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = x;
//newNode.prev = NULL; // You don't need this
newNode->next = first;
first = newNode;
printf("%d was pushed onto the stack.\n", first->data);
}
void pop()
{
struct node *prevPtr;
//if (first.data == '\0')
if (first == NULL) // check if stack is empty
{
printf("Error: Stack Empty.\n");
return;
}
printf("%d was popped off the stack.\n", first->data);
prevPtr = first;
first = first->next;
free(prevPtr);
}
問題是, first
是一個單一的全局node
,它是您擁有的唯一node
(除了您的push
調用中的臨時本地node
)。
這一行:
first = newNode;
只需將newNode
的內容復制到first
; 並且由於newNode.next
指向first
,這意味着現在first.next
指向first
,因此您有一個單元素循環鏈表。
同樣,這一行:
first = *(first.next);
只需將*(first.next)
的內容復制到first
; 這是一個無操作,因為(由於上述原因), *(first.next)
是 first
。
要解決此問題,您實際上需要使用malloc
(和free
)動態創建節點。 而你的全局first
變量應該是一個指針 - 一個node *
- 它總是指向堆棧的頂部元素。 (更好的是,你的push
和pop
函數應該first
作為參數,而不是將它作為一個全局變量。這些函數不需要只允許單個堆棧存在。)
&first
的價值是什么? 提示,它始終是相同的,因為first
是靜態分配。 即使您更改結構的內容,地址也不會更改。 這可能會告訴您為什么push
存在錯誤。 如果要使用不同大小的結構,則需要使用malloc
和free
。
當你必須自己管理內存時,正如C要求你做的那樣,你需要知道被稱為堆棧的內存區域和堆之間的區別。 (此“堆棧”與您在程序中創建的數據結構略有不同。)
你的push()
函數正在堆棧上創建一個新節點; 當函數退出堆棧時會彈出,並且新節點占用的內存可用於獲取。 您看到輸入的值的事實是由於您的程序非常簡單。 如果它正在調用執行其他操作的其他函數,那么它們幾乎肯定會覆蓋堆棧的那一部分,當你調用pop()
,你會看到垃圾。
正如其他人指出的那樣,你需要使用函數malloc()
和free()
,它們從堆而不是堆棧中提供內存。
如果要使用鏈表創建堆棧,請將first
變量作為指針。 然后,當您將新節點推送到堆棧時,通過malloc()分配堆內存來創建一個新節點。 我知道你打算用它來指向堆棧的頂部。 對?
在您的代碼中, first
變量被新節點覆蓋,因為它不是指針變量而是值變量。 這會導致丟失堆棧的頂級節點。
void pop()
{
struct node *prevPtr;
//if (first.data == '\0')
if (first == NULL)
{
printf("Error: Stack Empty.\n");
return;
}
printf("%d was popped off the stack.\n", first->data);
prevPtr = first;
first = first->next;
free(prevPtr);
}
#include<stdio.h>
# define max 10
int stack[max],top=-1,size=0;
void push()
{
if(top==(max-1))
{
printf("stack full\n");
}
else
{
top++;
printf("enter the value which you want to insert\n");
scanf("%d",&stack[top]);
}
}
void pop()
{
int str;
if(top==-1)
{
printf("stack empty\n");
}
else
{
str=stack[top];
top--;
printf("the removed element is %d\n",str);
}
}
void display()
{
int i;
for(i=0;i<top;i++)
{
printf("%d\n",stack[i]);
}
}
void main()
{
int enter,x;
do
{
printf("enter 1 for push the element in the array\n");
printf("enter 2 for pop the element in the array\n");
printf("enter 3 for display the element in the array\n");
scanf("%d",&enter);
switch(enter)
{
case 1:push();
break;
case 2:pop();
break;
case 3:display();
break;
default:
printf("invalid syntax");
}
printf("for continue press 0\n");
scanf("%d",&x);
}
while(x==0);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.