开发! 我在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]如何运作?
我真的不明白。
答案 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)