c - 更新嵌套 C 结构数组的正确方法是什么?

标签 c arrays struct parameter-passing pass-by-reference

我无法找到在 C99 中改变嵌套结构数组成员的正确方法(在将数组传递给另一个函数之后)。该数组在 main() 中声明 - 所以它在堆栈上,我想? - 而且,我还不如只展示代码的相关部分。

typedef struct
{
    uint32_t x, y;
} point;

typedef struct
{
    uint32_t r, g, b, a;
} rgba;

typedef struct
{
    point a, b, c;
    rgba p;
} tri;

那些是结构;这是我创建随机三角形的方法(我在程序的其他部分需要的能力):

tri triangle()
{
    tri t;

    t.a.x = rand() % xres;
    t.a.y = rand() % yres;
    t.b.x = rand() % xres;
    t.b.y = rand() % yres;
    t.c.x = rand() % xres;
    t.c.y = rand() % yres;
    t.p.r = rand() % 256;
    t.p.g = rand() % 256;
    t.p.b = rand() % 256;
    t.p.a = rand() % 256;

    return t;
}

这是我声明和填充数组的部分(有些行您可以忽略):

int main(int argc, char *argv[])
{
    init(argc, argv[1]);

    uint32_t img[xres][yres];

    copyInputImage(img);

    srand(time(NULL));

    tri trigons[NUM_TRIGONS];

    for (int i = 0; i < NUM_TRIGONS; i++)
    {
        trigons[i] = triangle();
    }

所有这些都成功地让我得到了一组随机三角形。

现在这是我的问题:根据程序参数,有时我想立即用文本文件中的数据重新填充数组。文本格式很简单:每行一个无符号字符。下面是该文件中单个像素数据的示例:

0
40
0
5
37
31
134
64
167
100

这是三角形结构最终需要的 10 个基元的示例。所有数字字符串都是 3 位或更少,但我使用 fgets() 的循环涉及一个 5 字符缓冲区以允许行终止符和空终止符。

执行此操作的函数如下所示:

void read_SVG(char* filename, tri* ts)
{
    FILE* fp = fopen(filename, "r");

    char str[5];

    for (int i = 0; i < NUM_TRIGONS; i++)
    {
        tri *t   = &(ts[i]);
        point *a = &(ts[i]).a;
        point *b = &(ts[i]).b;
        point *c = &(ts[i]).c;
        rgba  *p = &(ts[i]).p;

        while (fgets(str, 5, fp) != NULL)
        {
            a->x = (uint32_t) strtol(str, NULL, 10);
            a->y = (uint32_t) strtol(str, NULL, 10);
            b->x = (uint32_t) strtol(str, NULL, 10);
            b->y = (uint32_t) strtol(str, NULL, 10);
            c->x = (uint32_t) strtol(str, NULL, 10);
            c->y = (uint32_t) strtol(str, NULL, 10);
            p->r = (uint32_t) strtol(str, NULL, 10);
            p->g = (uint32_t) strtol(str, NULL, 10);
            p->b = (uint32_t) strtol(str, NULL, 10);
            p->a = (uint32_t) strtol(str, NULL, 10);
        }
        t->a = *a;
        t->b = *b;
        t->c = *c;
        t->p = *p;
    }
    fclose(fp);
}

最后,这就是我调用 read_SVG() 的方式,显示在 main() 的上下文中。

if (argc > 2)
{
    read_SVG(argv[2], trigons);

    draw(screen, trigons);
    SDL_Flip(screen);
    SDL_SaveBMP(screen, "wtf.bmp");
    exit(0);
}

当我从这个 read_SVG() 中输出数组时,它看起来像我预期的数据。但是当我在 main() 中检查它时,它看起来像是我最初填充的随机值。

所以看起来初始数组根本就没有更新过。我做错了什么,谁能建议一种整体更好的方法来处理此类嵌套结构传递和更新问题?

我敢肯定已经问了很多关于这个的问题;我只能希望我的内容足够全面,可以帮助其他一些 C 语言新手。在来这里寻求帮助之前,我尝试了多种方法...

最佳答案

这部分是多余的,因为 a、b、c 和 p 已经指向与 t 指向的同一内存:

    t->a = *a;
    t->b = *b;
    t->c = *c;
    t->p = *p;

但这只是一个吹毛求疵的问题。 ;) 重要 注释可能是 fgets() 将读取第一项的所有文件内容,而其余项不读取任何内容。也许 s/while/if/?

编辑澄清:这是 read_SVG() 函数的替代版本:

void read_SVG(char* filename, tri* ts)
{
    FILE* fp = fopen(filename, "r");
    char str[5];
    int i = 0;

    while (i < NUM_TRIGONS && fgets(str, 5, fp) != NULL) {
        uint32_t val = (uint32_t) strtol(str, NULL, 10);
        ts[i].a.x = ts[i].a.y = 
        ts[i].b.x = ts[i].b.y = 
        ts[i].c.x = ts[i].c.y = 
        ts[i].p.r = ts[i].p.g = ts[i].p.b = ts[i].p.a = val;

        i++;
    }
    fclose(fp);
}

关于c - 更新嵌套 C 结构数组的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40183858/

相关文章:

使用 boolean 值的条件表达式产生意外结果

c - 我如何使用 strace 了解我的 C 程序中的系统调用

c++ - 此数组中的某些值无特殊原因变为零 (0)

c - 如何在 C 中的同一个 ADT 中使用多种数据类型?

struct - Racket:从结构中提取字段 ID

struct - 如何在结构字段上创建可变迭代器

c - 为什么我总是得到8?

PHP 数组未设置

arrays - JDK 的数组与 Guava 的 ImmutableList

c++ - 在 OpenGL ES 2.0 中测量渲染到纹理的性能