为堆栈编写C pop函数

时间:2016-08-14 16:54:44

标签: c pointers stack

嘿我正在写一个堆栈函数,我在堆栈顶部弹出值时遇到了麻烦。我的推送功能似乎正在起作用。这是我推送和弹出的代码。

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函数,当我后递减指针时,值由于某种原因没有改变。有人可以帮我解释一下吗?任何帮助表示赞赏。

2 个答案:

答案 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;
}