嘿我正在写一个堆栈函数,我在堆栈顶部弹出值时遇到了麻烦。我的推送功能似乎正在起作用。这是我推送和弹出的代码。
void push(int num, int ** sp)
{
if (++(*sp) == NULL)
printf("Stack Overflow");
else{
printf("sp for push = %p \n", *sp);
**sp++ = num;
}
}
int pop(int **sp)
{
printf("sp for pop = %p\n", *sp);
num = (**sp)--;
printf("sp = %d\n",num);
printf("sp for pop = %p\n", *sp);
return num;
}
我也无法检查null条件以防止弹出甚至不在堆栈中的元素,但一次只出现一个问题。
无论如何,当我按15然后5
时,函数的输出看起来像这样sp for push = 0x1761014
sp for push = 0x1761018
sp for pop = 0x1761018
sp = 5
sp for pop = 0x1761018
5
其中sp是堆栈指针。注意堆栈指针如何通过sizeof int递增。我通过引用传递两个指针,所以它们都应该改变它们指向的内存中的位置,但是对于pop函数,当我后递减指针时,值由于某种原因没有改变。有人可以帮我解释一下吗?任何帮助表示赞赏。
答案 0 :(得分:0)
基本错误,我需要更改指向数据的指针的地址,而不是指向指针的指针。新代码是:
int pop(int **sp)
{
printf("sp for pop = %p\n", *sp);
num = (**sp);
(*sp)--;
printf("sp = %d\n",num);
printf("sp for pop = %p\n", *sp);
return num;
}
答案 1 :(得分:0)
在pop
中,您正在递减堆栈中的值而不是指向它的指针。请记住,*sp
是堆栈指针,而不是**sp
。因此,您需要递减*sp
而不是**sp
。
int pop(int **sp)
{
printf("sp for pop = %p\n", *sp);
/* num = (**sp)--; */ // ISSUE: Decrementing value instead of pointer
num = *(*sp)--;
printf("sp = %d\n",num);
printf("sp for pop = %p\n", *sp);
return num;
}
push
功能中也存在问题。虽然它现在不会产生问题,但最好修复它。
void push(int num, int ** sp)
{
if (++(*sp) == NULL)
printf("Stack Overflow");
else{
printf("sp for push = %p \n", *sp);
// **sp++ = num; // ISSUE: increment not needed.
// Once incremented, it will NOT point
// to stack pointer anymore
**sp = num;
}
}
要在弹出时检查堆栈中是否有空间,并在弹出时检查是否存在任何元素,可以使用index
变量来跟踪堆栈中的元素数量。
假设堆栈的最大容量为N
。将index
初始化为0
。
现在无论何时推送,首先检查是否index < N
,然后只推(并index
增加1
)。如果index
不小于N
,那么您有stackoverflow。
每当您弹出时,首先检查index > 0
是否为decrement
,然后仅弹出(index
1
index
。如果0
不大于index
,则您无法弹出元素。
另外,值得一提的是,如果这个sp
被命名为堆栈指针 - base
- 它指向堆栈的顶部,则更自然。您可以将指针传递给堆栈的基础并将其称为void push(int num, int *base, int sp) { ... } // base: start address of stack,
int pop(int *base, int sp) { ... } // sp: index of top of stack
或其他内容。那么你的职能就是:
bool LineRectIntersection(Vector2 lineStartPoint, Vector2 lineEndPoint, Rect rectangle, ref double resultX, ref double resultY)
{
Vector2 minXLinePoint = (lineStartPoint.x <= lineEndPoint.x) ? (lineStartPoint) : (lineEndPoint);
Vector2 maxXLinePoint = (lineStartPoint.x <= lineEndPoint.x) ? (lineEndPoint) : (lineStartPoint);
Vector2 minYLinePoint = (lineStartPoint.y <= lineEndPoint.y) ? (lineStartPoint) : (lineEndPoint);
Vector2 maxYLinePoint = (lineStartPoint.y <= lineEndPoint.y) ? (lineEndPoint) : (lineStartPoint);
double rectMaxX = rectangle.xMax;
double rectMinX = rectangle.xMin;
double rectMaxY = rectangle.yMax;
double rectMinY = rectangle.yMin;
if (minXLinePoint.x <= rectMaxX && rectMaxX <= maxXLinePoint.x)
{
double m = (maxXLinePoint.y - minXLinePoint.y) / (maxXLinePoint.x - minXLinePoint.x);
double intersectionY = ((rectMaxX - ((double)minXLinePoint.x)) * m) + ((double)minXLinePoint.y);
if(minYLinePoint.y <= intersectionY && intersectionY <= maxYLinePoint.y)
{
resultX = rectMaxX;
resultY = intersectionY;
return true;
}
}
if (minXLinePoint.x <= rectMinX && rectMinX <= maxXLinePoint.x)
{
double m = (maxXLinePoint.y - minXLinePoint.y) / (maxXLinePoint.x - minXLinePoint.x);
double intersectionY = ((rectMinX - ((double)minXLinePoint.x)) * m) + ((double)minXLinePoint.y);
if (minYLinePoint.y <= intersectionY && intersectionY <= maxYLinePoint.y)
{
resultX = rectMinX;
resultY = intersectionY;
return true;
}
}
if (minYLinePoint.y <= rectMaxY && rectMaxY <= maxYLinePoint.y)
{
double rm = (maxYLinePoint.x - minYLinePoint.x) / (maxYLinePoint.y - minYLinePoint.y);
double intersectionX = ((rectMaxY - ((double)minYLinePoint.y)) * rm) + ((double)minYLinePoint.x);
if (minXLinePoint.x <= intersectionX && intersectionX <= maxXLinePoint.x)
{
resultX = intersectionX;
resultY = rectMaxY;
return true;
}
}
if (minYLinePoint.y <= rectMinY && rectMinY <= maxYLinePoint.y)
{
double rm = (maxYLinePoint.x - minYLinePoint.x) / (maxYLinePoint.y - minYLinePoint.y);
double intersectionX = ((rectMinY - ((double)minYLinePoint.y)) * rm) + ((double)minYLinePoint.x);
if (minXLinePoint.x <= intersectionX && intersectionX <= maxXLinePoint.x)
{
resultX = intersectionX;
resultY = rectMinY;
return true;
}
}
return false;
}