【问题标题】:C99 Initialize an array through a pointer with bracesC99 通过带大括号的指针初始化数组
【发布时间】:2021-09-26 16:09:40
【问题描述】:

我写了一个函数,它计算一个正方形的所有顶点,给定它的位置和高度。由于不能在 C 中返回数组,我必须通过指针来完成。这是我最终编写的代码:

// Creates a rectangle for mapping a texture. Array must be 20 elements long.
void make_vertex_rect(float x, float y, float w, float h, float *vertex_positions) {
    /*  -1.0,+1.0             +1.0,+1.0
        +----------------------+
        |                      |
        |                      |
        |                      |
        +----------------------+
        -1.0,-1.0             +1.0,-1.0 */
    float new_positions[20] = {
        // We start at the top left and go in clockwise direction.
        //  x,     y,        z,    u,    v
            x,     y,     0.0f, 0.0f, 0.0f,
            x + w, y,     0.0f, 1.0f, 0.0f,
            x + w, y - h, 0.0f, 1.0f, 1.0f,
            x,     y - h, 0.0f, 0.0f, 1.0f
    };
    for (int i = 0; i < 20; ++i) { vertex_positions[i] = new_positions[i]; }
}

现在,由于 C99 提供了指定的初始化程序,我认为可能有一种方法可以在不编写 for 循环的情况下执行此操作,但无法弄清楚。有没有办法直接做到这一点,比如:

// Creates a rectangle for mapping a texture. Array must be 20 elements long.
void make_vertex_rect(float x, float y, float w, float h, float *vertex_positions) {
    // Does not compile, but is there a way to get it to compile with a cast or something?
    *vertex_positions = { ... }; 
}

【问题讨论】:

    标签: c c99 designated-initializer


    【解决方案1】:

    不,初始化器只能用于在声明对象时初始化对象。您不能使用它们来覆盖已经存在的数组。

    要么编写您的 for 循环,要么使用 memcpy,或者只写出目标数组元素的赋值。

    【讨论】:

    • 我希望有办法做到这一点,但事实并非如此。
    【解决方案2】:

    您可以在这里做的最好的事情是将显式循环替换为对 memcpy 的调用:

    memcpy(vertex_positions, new_positions, sizeof new_positions);
    

    或者通过手动分配给每个数组元素来实质上展开循环,即:

    int i=0;
    vertex_positions[i++] = x;
    vertex_positions[i++] = y;
    ...
    

    在此处使用i 作为索引,如果您想更改内容或在排序中出错,可以更轻松地重新排序分配。

    【讨论】:

    • 确保#include &lt;string.h&gt;
    【解决方案3】:

    由于不能在 C 中返回数组,我必须通过指针来完成

    这是真的。您不能直接返回数组,但可以返回包含数组的结构。这是一个解决方法:

    struct rect {
        float vertices[4][5];
    };
    
    struct rect make_vertex_rect(float x, float y, float w, float h) {
       return (struct rect) {{
           {x,     y,     0.0f, 0.0f, 0.0f},
           {x + w, y,     0.0f, 1.0f, 0.0f},
           {x + w, y - h, 0.0f, 1.0f, 1.0f},
           {x,     y - h, 0.0f, 0.0f, 1.0f}
       }};
    }
    

    显然,您可以将rect 的定义更改为您认为最合适的任何内容,这主要是为了说明这一点。只要数组大小是恒定的(就像这里一样),就没有问题。

    【讨论】:

      【解决方案4】:

      你的方法是最简单的。您必须填写分配在别处的 vertex_position 表的 20 个元素。它只能通过元素的原始复制元素或动态分配的内存来完成,但这需要更长的时间。

      【讨论】:

        猜你喜欢
        • 2019-08-04
        • 1970-01-01
        • 1970-01-01
        • 2020-02-08
        • 2021-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多