函数导致通过引用传递的变量行为异常

时间:2018-07-22 15:31:28

标签: c function pointers sdl pass-by-reference

我有一个使用SDL2的C程序。当PenTool的内容不在函数中,而是在调用函数的地方时,我有一个工作程序,但是将其放入函数中引起了一个我无法理解的问题。避免使用全局变量,我已经通过引用传递了需要处理的所有变量,包括PenTool bresline中的函数。通过使当前鼠标的坐标作为终点,而先前的鼠标的坐标作为直线的起点,该代码应该从鼠标绘制一条连续的线。但是,在此功能布局中,当前鼠标坐标被正确识别并绘制在屏幕上,但是先前的鼠标坐标保持不变,从而导致从同一点开始绘制的每条线,而不是实际的先前鼠标位置。此外,打印功能将所有变量显示为在鼠标移动时保持不变,尽管我的鼠标所在的程序正在运行。

问题出在bresline上。当我将其注释掉时,打印功能会显示所有变量随鼠标移动而正确更新,所以有人可以解释一下bresline为何阻止正确分配以前的鼠标坐标,以及为什么阻止printf显示正确的鼠标坐标。

我已经查看了StackOverflow上的其他问题以及通过引用正确传递的其他问题,并且据我所知,我正确传递了变量,并且我不知道如何阅读 C ++ / Java 所以这些答案无济于事,所以我真的不知道我要去哪里错了。

void bresline(SDL_Renderer *,int *, int *, int *, int *, Uint32 *);
void PenTool(int, int *, int *, SDL_Point, int *, int *, SDL_Renderer *, Uint32 *);

int main(void)
{
    int mouseX = 0, mouseY = 0, prevMouseX = 0, prevMouseY = 0;
    int penSize = 1;
...
    case SDL_MOUSEMOTION:
        if(leftMouseButtonDown)
        {
            PenTool(penSize, &mouseX, &mouseY, mouse_position, &prevMouseX, 
                &prevMouseY, renderer, pixels);
        }
...
void bresline(SDL_Renderer *renderer, int *x0, int *y0, int *xn, int *yn, Uint32 *pixels)
{
    int dx = abs(*xn-*x0), sx = *x0<*xn ? 1 : -1;
    int dy = abs(*yn-*y0), sy = *y0<*yn ? 1 : -1; 
    int error = (dx>dy ? dx : -dy)/2, e2;
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    while(1)
    {
        pixels[*y0 * 1000 + *x0] = 0;
        if(*x0==*xn && *y0==*yn) break;
        e2 = error;
        if(e2 >-dx)
        {
            error -= dy;
            *x0 += sx;
        }
        if(e2 < dy)
        {
            error += dx;
            *y0 += sy;
        }
    }
}

void PenTool(int penSize, int *mouseX, int *mouseY, SDL_Point mouse_position, 
    int *prevMouseX, int *prevMouseY, SDL_Renderer *renderer, Uint32 *pixels)
{
    if(penSize == 1)
    {
        *mouseX = mouse_position.x;
        *mouseY = mouse_position.y;
        if((*prevMouseX == 0) && (*prevMouseY == 0))
        {
            *prevMouseX = *mouseX;
            *prevMouseY = *mouseY;
        }
        bresline(renderer, mouseX, mouseY, prevMouseX, prevMouseY, pixels);
        *prevMouseX = *mouseX;
        *prevMouseY = *mouseY;
        printf("M1_x: %d, M1_y: %d, M2_x: %d, M2_y: %d \n", *mouseX, *mouseY, *prevMouseX, *prevMouseY);
    }
}

1 个答案:

答案 0 :(得分:0)

顺便说一句,我将改用bresline:

void bresline(SDL_Renderer *,int , int , int , int , Uint32 *);

void bresline(SDL_Renderer *renderer, int x0, int y0, int xn, int yn, Uint32 *pixels)
{
    int dx = abs(xn-x0), sx = x0<xn ? 1 : -1;
    int dy = abs(yn-y0), sy = y0<yn ? 1 : -1; 
    int error = (dx>dy ? dx : -dy)/2, e2;
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    while(1)
    {
        pixels[y0 * 1000 + x0] = 0;
        if(x0==xn && y0==yn) break;
        e2 = error;
        if(e2 >-dx)
        {
            error -= dy;
            x0 += sx;
        }
        if(e2 < dy)
        {
            error += dx;
            y0 += sy;
        }
    }
}

在代码中,您正在更改Bresenham算法函数中的值,因此,当函数退出时,MouseX和MouseY始终将分别为PrevMouseX和PrevMouseY。那可以解释您总是从同一点开始的问题。


并更改为此调用函数的方式:

bresline(renderer, *mouseX, *mouseY, *prevMouseX, *prevMouseY, pixels);