C99 通过带大括号的指针初始化数组
C99 Initialize an array through a pointer with braces
我写了一个函数,它计算一个正方形的所有顶点,给定它的位置和高度。由于在 C 中不能 return 数组,所以我必须通过指针来完成。这是我最终写的代码:
// 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 = { ... };
}
不,初始化程序只能用于初始化 声明的对象。您不能使用它们来覆盖已经存在的数组。
要么编写 for
循环,要么使用 memcpy
,或者只写出对目标数组元素的赋值。
您在这里可以做的最好的事情是用对 memcpy
:
的调用替换显式循环
memcpy(vertex_positions, new_positions, sizeof new_positions);
或者通过手动分配给每个数组元素来基本上展开循环,即:
int i=0;
vertex_positions[i++] = x;
vertex_positions[i++] = y;
...
此处使用 i
作为索引,如果您想更改内容或在排序时出错,可以更轻松地重新排序作业。
Since one cannot return array's in C I have to do it through a pointer
这是真的。你不能直接 return 一个数组,但是你可以 return 一个包含数组的结构。这是一个解决方法:
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
的定义更改为您认为最合适的任何定义,这主要只是为了说明这一点。只要数组大小不变(因为它们在这里),就没有问题。
你的方法最简单。您必须填写分配在别处的 vertex_position table 的 20 个元素。只能通过逐个元素原始复制或动态分配内存来完成,但这需要更长的时间。
我写了一个函数,它计算一个正方形的所有顶点,给定它的位置和高度。由于在 C 中不能 return 数组,所以我必须通过指针来完成。这是我最终写的代码:
// 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 = { ... };
}
不,初始化程序只能用于初始化 声明的对象。您不能使用它们来覆盖已经存在的数组。
要么编写 for
循环,要么使用 memcpy
,或者只写出对目标数组元素的赋值。
您在这里可以做的最好的事情是用对 memcpy
:
memcpy(vertex_positions, new_positions, sizeof new_positions);
或者通过手动分配给每个数组元素来基本上展开循环,即:
int i=0;
vertex_positions[i++] = x;
vertex_positions[i++] = y;
...
此处使用 i
作为索引,如果您想更改内容或在排序时出错,可以更轻松地重新排序作业。
Since one cannot return array's in C I have to do it through a pointer
这是真的。你不能直接 return 一个数组,但是你可以 return 一个包含数组的结构。这是一个解决方法:
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
的定义更改为您认为最合适的任何定义,这主要只是为了说明这一点。只要数组大小不变(因为它们在这里),就没有问题。
你的方法最简单。您必须填写分配在别处的 vertex_position table 的 20 个元素。只能通过逐个元素原始复制或动态分配内存来完成,但这需要更长的时间。