在C编程中实现堆栈的推送方法

时间:2018-06-10 08:06:24

标签: c data-structures stack

开发! 我在C中有一个堆栈的push()方法的问题!

我在C中实现了自己的push()方法! 但我无法理解结果!

我的堆栈代码

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 10

int top = -1;
int array[MAX_SIZE];

void init(){
    top = -1;
}

void push(int array[], int data){

    if(top > MAX_SIZE-1)
        fprintf(stderr, "invalid top %d\n", top+1);
    else{
        array[++top] = data; // top == 9, ++top == 10
        printf("top: %d data: %d\n", top+1, array[top]); // top == 11, top == 10
    }
}
void pop(int array[]){

}
void peek(int array[]){

}

int main() {
   int data = 1;

   for (int i=0; i<MAX_SIZE; i++)
        push(array, data++);
   push(array, 100);
   push(array, 200); // invalid top
   push(array, 300); // invalid top
   return 0;
}

,此代码的结果在

之下
top: 1 data: 1
top: 2 data: 2
top: 3 data: 3
top: 4 data: 4
top: 5 data: 5
top: 6 data: 6
top: 7 data: 7
top: 8 data: 8
top: 9 data: 9
top: 10 data: 10
top: 11 data: 100
invalid top 11 
invalid top 11

我不明白的是...... 在结果中,当top:11,实际上,它就像top:top + 1。 如果你在我的push()方法中查看else语句,你可以注意到它。

但是,在其他声明中, 当

printf("top: %d data: %d\n", 11, array[10]);
the result: top: 11 data: 100

,我认为这应该是一个错误。因为我声明数组大小为10,即MAX_SIZE。所以索引大小为0~9。 但是数组[10]如何运作?

我真的不明白。

4 个答案:

答案 0 :(得分:5)

你可以这样做,因为C允许你这样做。但是你不应该因为在未分配的内存区域写入是危险的。您的数组已分配10个长度的整数。分配内存的10个整数。您尝试访问的第11个整数没有为其分配内存。

如评论中所述,如果您希望代码抛出错误,您想要的功能是绑定检查。它正是您在push函数的第一部分所做的事情。

将您的条件更改为top >= MAX_SIZE - 1以解决问题。

至于实现堆栈的更好方法,您可以尝试在链表上实现一个,这允许您在已停止的内存区域中管理堆栈。

您也可以将unsigned int用于数组索引,因为那里不需要负数。

答案 1 :(得分:2)

你真的需要学习基本的调试。例如,最基本的是找出代码中某些点的值。这可以通过调试器或简单的打印语句来完成。

我这样做了:

void push(int array[], int data){
    printf("%d\n", top);

    if(top > MAX_SIZE-1)
        fprintf(stderr, "invalid top %d\n", top+1);
    else{
        array[++top] = data; // top == 9, ++top == 10
        printf("top: %d data: %d\n", top+1, array[top]); // top == 11, top == 10
    }
}

得到了这个输出:

...
top: 9 data: 9
8
top: 10 data: 10
9
top: 11 data: 100
10
invalid top 11
10
invalid top 11

现在应该很清楚问题是什么。

  

我认为这应该是一个错误。因为我声明数组大小为10,即MAX_SIZE。因此索引大小将为0~9。但是数组[10]如何工作?

它不起作用。它确实“有效”。访问越界会导致未定义的行为。请阅读此处了解更多信息:https://stackoverflow.com/a/4105123/6699433

答案 2 :(得分:1)

实际上,在你的代码顶部是-1而与max_size-1比较,这意味着9,条件为真,直到top的值为9.这意味着top = -1,0,1,2的10倍,3,4,5,6,7,8。因此,直到数组[10]才有效。

请尝试以下代码。

select Table1.id, Table1.name, Table2.table1_id from Table1, Table1 where Table2.table1_id == Table1.id

我认为这就是你想要的。

  #include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 10

int top = -1;
int array[MAX_SIZE];

void init(){
    top = -1;
}

void push(int array[], int data){
++top;
    if(top > MAX_SIZE-1)
        fprintf(stderr, "invalid top %d\n", top+1);
    else{
        array[top] = data; // top == 9, ++top == 10
        printf("top: %d data: %d\n", top+1, array[top]); // top == 11, top == 10
    }
}
void pop(int array[]){

}
void peek(int array[]){

}

int main() {
   int data = 1;

   for (int i=0; i<MAX_SIZE; i++)
        push(array, data++);
   push(array, 100);
   push(array, 200); // invalid top
   push(array, 300); // invalid top
   return 0;
}

答案 3 :(得分:1)

作为对其他答案的补充,我想使用struct为您的堆栈添加更方便的实现。程序的行为稍有改变,可能是想要的。

#include <stdio.h>

#define MAX_SIZE 10

typedef struct Stack Stack;
void stackPush(Stack* s, int data);

struct Stack{
    unsigned int head;
    int arr[MAX_SIZE];

    void(*push)(Stack* s, int data);
};

void stackPush(Stack* s, int data) {
    if (s->head < MAX_SIZE) {
        s->arr[s->head] = data;  // push to stack
        printf("Head: %d. Data: %d.\n", s->head, s->arr[s->head]); 
        s->head++;  // move forward
    }

    else
        fprintf(stderr, "Stack is full! (head at: %d)\n", s->head);
}

int main() {
    // Initialize the stack
    Stack s;
    s.head = 0;
    s.push = stackPush;

    // Push the data
    int data = 1;

    int i;
    for (i = 0; i < MAX_SIZE; i++)
        s.push(&s, data++);

    s.push(&s, 100); // 
    s.push(&s, 200); // trying to push to a full stack
    s.push(&s, 300); // 

    return 0;
}

将输出

Head: 0. Data: 1.
Head: 1. Data: 2.
Head: 2. Data: 3.
Head: 3. Data: 4.
Head: 4. Data: 5.
Head: 5. Data: 6.
Head: 6. Data: 7.
Head: 7. Data: 8.
Head: 8. Data: 9.
Head: 9. Data: 10.
Stack is full! (head at: 10)
Stack is full! (head at: 10)
Stack is full! (head at: 10)