0

X ウィンドウに図形を描画するイベント ドリブン プロジェクトに取り組んでいます。画面上でマウスをクリックするたびに、x と y の新しい値が生成されます。私の質問は、マウスをクリックするたびに x と y の新しい値が生成されると仮定して、以下のコードに x と y の異なる値をどのように格納できるかということです。

int x, y;
x = report.xbutton.x;
y = report.xbutton.y;

if (report.xbutton.button == Button1) {
    XFillArc(display_ptr, win, gc_red, 
             x - win_height/80, y - win_height/80,
             win_height/60, win_height/60, 0, 360*64);
}
4

1 に答える 1

0

コードの1つのバージョンは次のようになります。

typedef struct Position
{
    int x;
    int y;
} Position;

typedef struct PosnList
{
    size_t     num_pts;
    size_t     max_pts;
    Position  *points;
} PosnList;

void add_point(int x, int y, PosnList *p)
{
    if (p->num_pts >= p->max_pts)
    {
        size_t new_num = (p->max_pts + 2) * 2;
        Position *new_pts = realloc(p->points, new_num * sizeof(Position));
        if (new_pts == 0)
            ...handle out of memory error...
        p->max_pts = new_num;
        p->points  = new_pts;
    }
    p->points[p->num_pts++] = (Position){ x, y };
}

void zap_posnlist(PosnList *p)
{
     free(p->points);
     p->num_pts = 0;
     p->max_pts = 0;
     p->points  = 0;
}

次に、コードは次のようになります。

int x, y;
x = report.xbutton.x;
y = report.xbutton.y;

if (report.xbutton.button == Button1) {
    XFillArc(display_ptr, win, gc_red, 
             x - win_height/80, y - win_height/80,
             win_height/60, win_height/60, 0, 360*64);
    add_point(x, y, &positions);
}

どこかに変数があります:

PosnList positions = { 0, 0, 0 };

このadd_point()関数はrealloc()、初期メモリ割り当てと増分メモリ割り当ての両方を実行するために使用することに注意してください。xこのコードは、C99複合リテラルを使用して、値と配列内yの次の値を割り当てます。PositionC99をお持ちでない場合は、2つの別々の割り当てを行う必要があります。

このzap_posnlist()関数は、以前に初期化されたを解放しますPosnListPosnList xxx = { 0, 0, 0 };どこでも表記法を使用することに満足していない限り、正式な初期化関数が必要になる場合があります。

このコードは現在GCCによってサニタイズされています。元のエディションはそうではなく、バグがありました—コンパイラエラーを生成するバグ。


テスト済みのコード—"stderr.h"これは標準のヘッダーではありませんが、私が日常的に使用しているエラー報告コードであることに注意してください。err_error()および機能を提供しerr_setarg0()ます。

#include <stdlib.h>
#include "stderr.h"

typedef struct Position
{
    int x;
    int y;
} Position;

typedef struct PosnList
{
    size_t     num_pts;
    size_t     max_pts;
    Position  *points;
} PosnList;

extern void add_point(int x, int y, PosnList *p);
extern void zap_posnlist(PosnList *p);

void add_point(int x, int y, PosnList *p)
{
    if (p->num_pts >= p->max_pts)
    {
        size_t new_num = (p->max_pts + 2) * 2;
        Position *new_pts = realloc(p->points, new_num * sizeof(Position));
        if (new_pts == 0)
            err_error("Out of memory (%s:%d - %zu bytes)\n",
                       __FILE__, __LINE__, new_num * sizeof(Position));
        p->max_pts = new_num;
        p->points  = new_pts;
    }
    p->points[p->num_pts++] = (Position){ x, y };
}

void zap_posnlist(PosnList *p)
{
    free(p->points);
    p->num_pts = 0;
    p->max_pts = 0;
    p->points  = 0;
}

#include <stdio.h>

int main(int argc, char **argv)
{
    PosnList positions = { 0, 0, 0 };

    err_setarg0(argv[0]);

    if (argc > 1)
        srand(atoi(argv[1]));

    for (size_t i = 0; i < 37; i++)
        add_point(rand(), rand(), &positions);

    for (size_t i = 0; i < positions.num_pts; i++)
        printf("%2zu: (%5d, %5d)\n", i, positions.points[i].x, positions.points[i].y);

    zap_posnlist(&positions);
    return(0);
}

stderr.hおよびのソースが必要な場合は、私に連絡してください(私のプロファイルを参照してください)stderr.c

于 2012-09-26T13:53:26.863 に答える