有没有办法以压缩的形式做到这一点?
GLfloat coordinates[8];
...
coordinates[0] = 1.0f;
coordinates[1] = 0.0f;
coordinates[2] = 1.0f;
coordinates[3] = 1.0f;
coordinates[4] = 0.0f;
coordinates[5] = 1.0f;
coordinates[6] = 0.0f;
coordinates[7] = 0.0f;
return coordinates;
类似
coordinates = {1.0f, ...};
的东西?
如果你真的要分配值(而不是初始化),你可以这样做:
GLfloat coordinates[8];
static const GLfloat coordinates_defaults[8] = {1.0f, 0.0f, 1.0f ....};
...
memcpy(coordinates, coordinates_defaults, sizeof(coordinates_defaults));
return coordinates;
尽管在您的情况下,只需简单的初始化即可,但有一个技巧可以将数组包装到结构中(可以在声明后初始化)。
例如:
struct foo {
GLfloat arr[10];
};
...
struct foo foo;
foo = (struct foo) { .arr = {1.0, ... } };
老式方法:
GLfloat coordinates[8];
...
GLfloat *p = coordinates;
*p++ = 1.0f; *p++ = 0.0f; *p++ = 1.0f; *p++ = 1.0f;
*p++ = 0.0f; *p++ = 1.0f; *p++ = 0.0f; *p++ = 0.0f;
return coordinates;
您可以使用:
GLfloat coordinates[8] = {1.0f, ..., 0.0f};
但这是一个编译时初始化 - 您不能在当前标准中使用该方法来重新初始化(尽管我认为在即将推出的标准中有一些方法可以做到这一点,这可能不会立即帮助您)。
我想到的另外两种方法是,如果内容已修复,则将其删掉:
GLfloat base_coordinates[8] = {1.0f, ..., 0.0f};
GLfloat coordinates[8];
:
memcpy (coordinates, base_coordinates, sizeof (coordinates));
或者提供一个看起来像你的初始化代码的函数:
void setCoords (float *p0, float p1, ..., float p8) {
p0[0] = p1; p0[1] = p2; p0[2] = p3; p0[3] = p4;
p0[4] = p5; p0[5] = p6; p0[6] = p7; p0[7] = p8;
}
:
setCoords (coordinates, 1.0f, ..., 0.0f);
请记住,这些省略号 (
...
) 是占位符,而不是直接插入代码中的内容。
我采用了数组初始化方法:
#include <stdarg.h>
void int_array_init(int *a, const int ct, ...) {
va_list args;
va_start(args, ct);
for(int i = 0; i < ct; ++i) {
a[i] = va_arg(args, int);
}
va_end(args);
}
称为喜欢,
const int node_ct = 8;
int expected[node_ct];
int_array_init(expected, node_ct, 1, 3, 4, 2, 5, 6, 7, 8);
C99数组初始化,像这样:
const int node_ct = 8;
const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };
在
configure.ac
:
AC_PROG_CC_C99
我的开发盒上的编译器非常满意。服务器上的编译器抱怨:
error: variable-sized object may not be initialized
const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };
和
warning: excess elements in array initializer
const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };
对于每个元素
它根本不抱怨,例如:
int expected[] = { 1, 2, 3, 4, 5 };
我喜欢对大小的检查,并且可变参数支持比对数组初始值设定项的支持表现得更稳健。
在 https://github.com/wbreeze/davenport/pull/15/files 找到带有示例代码的 PR
关于来自@paxdiablo的https://stackoverflow.com/a/3535455/608359,我喜欢它;但是,对于初始化指针前进的次数与分配给数组的元素数同步感到不安全。最坏的情况是,初始化指针超出了分配的长度。因此,PR 中的差异包含,
int expected[node_ct];
- int *p = expected;
- *p++ = 1; *p++ = 2; *p++ = 3; *p++ = 4;
+ int_array_init(expected, node_ct, 1, 2, 3, 4);
int_array_init
方法将安全地分配垃圾,如果数量
参数少于node_ct。垃圾任务应该更容易
捕获和调试。
没错,你几乎明白了:
GLfloat coordinates[8] = {1.0f, ..., 0.0f};
如果您在程序中经常执行这些相同的任务并且想要快捷方式,最直接的解决方案可能就是添加一个函数
static inline void set_coordinates(
GLfloat coordinates[static 8],
GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3,
GLfloat c4, GLfloat c5, GLfloat c6, GLfloat c7)
{
coordinates[0] = c0;
coordinates[1] = c1;
coordinates[2] = c2;
coordinates[3] = c3;
coordinates[4] = c4;
coordinates[5] = c5;
coordinates[6] = c6;
coordinates[7] = c7;
}
然后只需致电
GLfloat coordinates[8];
// ...
set_coordinates(coordinates, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f);
您可以使用
_Generic
和 __VA_ARGS__
编写通用数组赋值宏。它不需要传递的参数数量。但它已经NULL
终止了;这意味着您不能分配 NULL
又名 0。(您可以放置除 NULL
之外的其他内容,您知道您不会分配)。
#define ARRAY_ASSIGN(arr, ...) _Generic(arr, \
GLfloat* : GLfloat_array_assign(arr, __VA_ARGS__, NULL))
#define GEN_ARRAY_ASSIGN_FUNC(type) \
inline void type ## _array_assign(type* a, ...) { \
va_list list; \
va_start(list, a); \
int count = 0; \
type arg = va_arg(list, type); \
while (arg) { \
a[count++] = arg; \
arg = va_arg(list, type); \
} \
va_end(list); \
}
GEN_ARRAY_ASSIGN_FUNC(GLfloat);
您为每种类型调用
GEN_ARRAY_ASSIGN_FUNC
并将类型添加到 _Generic
参数中。
并像这样使用它:
ARRAY_ASSIGN(coordinates, 1.f, 2.f, 3.f, 4.f);
或者如果您更喜欢提供计数而不是
NULL
终止:
#define ARRAY_ASSIGN(arr, count, ...) _Generic(arr, \
GLfloat* : GLfloat_array_assign(arr, count, __VA_ARGS__))
#define GEN_ARRAY_ASSIGN_FUNC(type) \
inline void type ## _array_assign(type* a, int count, ...) { \
va_list list; \
va_start(list, count); \
type arg = va_arg(list, type); \
for (int i=0; i<count; i++) { \
a[i] = arg; \
arg = va_arg(list, type); \
} \
va_end(list); \
}
并且:
ARRAY_ASSIGN(coordinates, 4, 1.f, 0.f, 1.f, 0.f);
typedef struct{
char array[4];
}my_array;
my_array array = { .array = {1,1,1,1} }; // initialisation
void assign(my_array a)
{
array.array[0] = a.array[0];
array.array[1] = a.array[1];
array.array[2] = a.array[2];
array.array[3] = a.array[3];
}
char num = 5;
char ber = 6;
int main(void)
{
printf("%d\n", array.array[0]);
// ...
// this works even after initialisation
assign((my_array){ .array = {num,ber,num,ber} });
printf("%d\n", array.array[0]);
// ....
return 0;
}