C 这个定义语句是什么意思?

C 这个定义语句是什么意思?,c,c-preprocessor,C,C Preprocessor,我有一段代码可以在屏幕上画一个椭圆,但我不明白长的define语句意味着什么,我只想知道如何编写相同的代码,而不让define语句混淆 #define incx() x++, dxt += d2xt, t += dxt #define incy() y--, dyt += d2yt, t += dyt void ellipse(int xc, int yc, int rx, int ry, int color) { int x = 0, y = ry; long rx2 =

我有一段代码可以在屏幕上画一个椭圆,但我不明白长的define语句意味着什么,我只想知道如何编写相同的代码,而不让define语句混淆

#define incx() x++, dxt += d2xt, t += dxt 
#define incy() y--, dyt += d2yt, t += dyt

void ellipse(int xc, int yc, int rx, int ry, int color)
{
    int x = 0, y = ry;
    long rx2 = (long)rx*rx, ry2 = (long)ry*ry;
    long crit1 = -(rx2/4 + rx%2 + ry2);
    long crit2 = -(ry2/4 + ry%2 + rx2);
    long crit3 = -(ry2/4 + ry%2);
    long t = -rx2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4
    long dxt = 2*ry2*x, dyt = -2*rx2*y;
    long d2xt = 2*ry2, d2yt = 2*rx2;

    while (y>=0 && x<=rx)
    {
        pixel(xc+x, yc+y, color);
        if (x!=0 || y!=0)
            pixel(xc-x, yc-y, color);
        if (x!=0 && y!=0)
        {
            pixel(xc+x, yc-y, color);
            pixel(xc-x, yc+y, color);
        }
        if (t + ry2*x <= crit1 ||   //e(x+1,y-1/2) <= 0
            t + rx2*y <= crit3)     //e(x+1/2,y) <= 0
            incx();
        else if (t - rx2*y > crit2) //e(x+1/2,y-1) > 0
            incy();
        else
        {
            incx();
            incy();
        }
    }
}
#定义incx()x++,dxt+=d2xt,t+=dxt
#定义incy()y--,dyt+=d2yt,t+=dyt
空心椭圆(整数xc、整数yc、整数rx、整数ry、整数颜色)
{
int x=0,y=ry;
长rx2=(长)rx*rx,ry2=(长)ry*ry;
长临界值1=-(rx2/4+rx%2+ry2);
长临界值2=-(ry2/4+ry%2+rx2);
长临界值3=-(ry2/4+ry%2);
长t=-rx2*y;//e(x+1/2,y-1/2)-(a^2+b^2)/4
长dxt=2*ry2*x,dyt=-2*rx2*y;
长d2xt=2*ry2,d2yt=2*rx2;

(y>=0&&x如果您只想删除它,请通过
cpp
运行代码:

 cpp cpp.c > cppout.c
给我

# 1 "cpp.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "cpp.c"



void ellipse(int xc, int yc, int rx, int ry, int color)
{
    int x = 0, y = ry;
    long rx2 = (long)rx*rx, ry2 = (long)ry*ry;
    long crit1 = -(rx2/4 + rx%2 + ry2);
    long crit2 = -(ry2/4 + ry%2 + rx2);
    long crit3 = -(ry2/4 + ry%2);
    long t = -rx2*y;
    long dxt = 2*ry2*x, dyt = -2*rx2*y;
    long d2xt = 2*ry2, d2yt = 2*rx2;

    while (y>=0 && x<=rx)
    {
        pixel(xc+x, yc+y, color);
        if (x!=0 || y!=0)
            pixel(xc-x, yc-y, color);
        if (x!=0 && y!=0)
        {
            pixel(xc+x, yc-y, color);
            pixel(xc-x, yc+y, color);
        }
        if (t + ry2*x <= crit1 ||
            t + rx2*y <= crit3)
            x++, dxt += d2xt, t += dxt;
        else if (t - rx2*y > crit2)
            y--, dyt += d2yt, t += dyt;
        else
        {
            x++, dxt += d2xt, t += dxt;
            y--, dyt += d2yt, t += dyt;
        }
    }
}
#define
由预处理器计算,并简单地用行的其余部分替换第一项的任何实例。因此,代码等价于以下内容:

void ellipse(int xc, int yc, int rx, int ry, int color)
{
    int x = 0, y = ry;
    long rx2 = (long)rx*rx, ry2 = (long)ry*ry;
    long crit1 = -(rx2/4 + rx%2 + ry2);
    long crit2 = -(ry2/4 + ry%2 + rx2);
    long crit3 = -(ry2/4 + ry%2);
    long t = -rx2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4
    long dxt = 2*ry2*x, dyt = -2*rx2*y;
    long d2xt = 2*ry2, d2yt = 2*rx2;

    while (y>=0 && x<=rx)
    {
        pixel(xc+x, yc+y, color);
        if (x!=0 || y!=0)
            pixel(xc-x, yc-y, color);
        if (x!=0 && y!=0)
        {
            pixel(xc+x, yc-y, color);
            pixel(xc-x, yc+y, color);
        }
        if (t + ry2*x <= crit1 ||   //e(x+1,y-1/2) <= 0
            t + rx2*y <= crit3)     //e(x+1/2,y) <= 0
            x++, dxt += d2xt, t += dxt;
        else if (t - rx2*y > crit2) //e(x+1/2,y-1) > 0
            y--, dyt += d2yt, t += dyt;
        else
        {
            x++, dxt += d2xt, t += dxt;
            y--, dyt += d2yt, t += dyt;
        }
    }
}
void椭圆(int-xc、int-yc、int-rx、int-ry、int-color)
{
int x=0,y=ry;
长rx2=(长)rx*rx,ry2=(长)ry*ry;
长临界值1=-(rx2/4+rx%2+ry2);
长临界值2=-(ry2/4+ry%2+rx2);
长临界值3=-(ry2/4+ry%2);
长t=-rx2*y;//e(x+1/2,y-1/2)-(a^2+b^2)/4
长dxt=2*ry2*x,dyt=-2*rx2*y;
长d2xt=2*ry2,d2yt=2*rx2;

当(y>=0&&x时,假设逗号是分号,因为这实际上就是它们的用途。宏可以写得更直接一些,如下所示:

#define incx() do { x++; dxt += d2xt; t += dxt; } while (0)
#define incy() do { y--; dyt += d2yt; t += dyt; } while (0)
#define incx() x++, dxt += d2xt, t += dxt 

if (t + ry2*x <= crit1 || t + rx2*y <= crit3)
    incx();
更直接的是,这三条语句以分号结尾。使用
do{}while(0)
loop,这是一种将多条语句转换为一条大语句的常用习惯用法

#define incx() x++, dxt += d2xt, t += dxt 
#define incy() y--, dyt += d2yt, t += dyt

void ellipse(int xc, int yc, int rx, int ry, int color)
{
    int x = 0, y = ry;
    long rx2 = (long)rx*rx, ry2 = (long)ry*ry;
    long crit1 = -(rx2/4 + rx%2 + ry2);
    long crit2 = -(ry2/4 + ry%2 + rx2);
    long crit3 = -(ry2/4 + ry%2);
    long t = -rx2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4
    long dxt = 2*ry2*x, dyt = -2*rx2*y;
    long d2xt = 2*ry2, d2yt = 2*rx2;

    while (y>=0 && x<=rx)
    {
        pixel(xc+x, yc+y, color);
        if (x!=0 || y!=0)
            pixel(xc-x, yc-y, color);
        if (x!=0 && y!=0)
        {
            pixel(xc+x, yc-y, color);
            pixel(xc-x, yc+y, color);
        }
        if (t + ry2*x <= crit1 ||   //e(x+1,y-1/2) <= 0
            t + rx2*y <= crit3)     //e(x+1/2,y) <= 0
            incx();
        else if (t - rx2*y > crit2) //e(x+1/2,y-1) > 0
            incy();
        else
        {
            incx();
            incy();
        }
    }
}
(虽然它看起来像一个循环,但它只会执行一次,然后结束,因为
while(0)
条件被保证为false。这个技巧的目的是在宏之后需要一个分号,所以您可以像普通函数一样使用它:
incx();
incy();


不管怎么说,这些宏的要点是将重复出现的
x++;dxt+=d2xt;t+=dxt;
替换为一个宏调用。这三个语句的序列经常重复,足以使重构变得有价值。

这意味着实际的代码已经变得太复杂,无法读取,以前的开发人员我求助于使用宏来提高可读性

由于他们没有留下注释-他们在C中失败了,
#define
由预处理器处理,它在编译器看到代码之前进行简单的文本替换。您有一个如下的源文件:

#define incx() do { x++; dxt += d2xt; t += dxt; } while (0)
#define incy() do { y--; dyt += d2yt; t += dyt; } while (0)
#define incx() x++, dxt += d2xt, t += dxt 

if (t + ry2*x <= crit1 || t + rx2*y <= crit3)
    incx();

这就是编译器实际看到并试图编译的内容。

对于“它在做什么”的更高层次的答案,它是计算一个微分方程的近似解来绘制椭圆;dxt、d2xt、dyt和d2yt变量是变化率(dx/dt、d^{2}x/dt^{2}、dy/dt、d^{2}y/dt 2},或多或少)。incx()和incy()宏一步一步地将方程中的所有变量一起更新,以确保它们保持同步。可以将其视为信息隐藏的一次非常小的尝试