在C中将多个值分配给数组

发布于 2024-09-15 17:09:26 字数 326 浏览 11 评论 0原文

有没有办法以压缩的形式做到这一点?

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;

坐标= {1.0f,...};之类的东西?

Is there any way to do this in a condensed form?

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;

Something like coordinates = {1.0f, ...};?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

风柔一江水 2024-09-22 17:09:26

如果您确实要分配值(而不是初始化),您可以这样做:

 GLfloat coordinates[8]; 
 static const GLfloat coordinates_defaults[8] = {1.0f, 0.0f, 1.0f ....};
 ... 
 memcpy(coordinates, coordinates_defaults, sizeof(coordinates_defaults));

 return coordinates; 

If you really to assign values (as opposed to initialize), you can do it like this:

 GLfloat coordinates[8]; 
 static const GLfloat coordinates_defaults[8] = {1.0f, 0.0f, 1.0f ....};
 ... 
 memcpy(coordinates, coordinates_defaults, sizeof(coordinates_defaults));

 return coordinates; 
心的憧憬 2024-09-22 17:09:26

尽管在您的情况下,只需简单的初始化即可,但有一个技巧可以将数组包装到结构中(可以在声明后初始化)。

例如:

struct foo {
  GLfloat arr[10];
};
...
struct foo foo;
foo = (struct foo) { .arr = {1.0, ... } };

Although in your case, just plain initialization will do, there's a trick to wrap the array into a struct (which can be initialized after declaration).

For example:

struct foo {
  GLfloat arr[10];
};
...
struct foo foo;
foo = (struct foo) { .arr = {1.0, ... } };
固执像三岁 2024-09-22 17:09:26

老派的方式:

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;

The old-school way:

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;
初心未许 2024-09-22 17:09:26

确切地说,你几乎明白了:

GLfloat coordinates[8] = {1.0f, ..., 0.0f};

Exactly, you nearly got it:

GLfloat coordinates[8] = {1.0f, ..., 0.0f};
栀子花开つ 2024-09-22 17:09:26

您可以使用:

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);

请记住这些省略号 (...) 是占位符,而不是从字面上插入到代码中的东西。

You can use:

GLfloat coordinates[8] = {1.0f, ..., 0.0f};

but this is a compile-time initialisation - you can't use that method in the current standard to re-initialise (although I think there are ways to do it in the upcoming standard, which may not immediately help you).

The other two ways that spring to mind are to blat the contents if they're fixed:

GLfloat base_coordinates[8] = {1.0f, ..., 0.0f};
GLfloat coordinates[8];
:
memcpy (coordinates, base_coordinates, sizeof (coordinates));

or provide a function that looks like your initialisation code anyway:

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);

keeping in mind those ellipses (...) are placeholders, not things to literally insert in the code.

回忆凄美了谁 2024-09-22 17:09:26

我采用了一种数组初始化方法:

#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/ 中查找带有示例代码的 PR 15/files

关于来自@paxdiablo的https://stackoverflow.com/a/3535455/608359,我喜欢它;但是,对于初始化指针前进的次数与分配给数组的元素数同步感到不安全。最坏的情况是,初始化指针超出了分配的长度。因此,PR 中的 diff 包含:

  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。垃圾任务应该更容易
捕获和调试。

I went with an array initialization method:

#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);
}

called like,

const int node_ct = 8;
int expected[node_ct];
int_array_init(expected, node_ct, 1, 3, 4, 2, 5, 6, 7, 8);

The C99 array initialization, like this:

const int node_ct = 8;
const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };

And in the configure.ac:

AC_PROG_CC_C99

had the compiler on my dev box perfectly happy. The compiler on the server complained with:

error: variable-sized object may not be initialized
   const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };

and

warning: excess elements in array initializer
   const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };

for each element

It doesn't complain at all about, for example:

int expected[] = { 1, 2, 3, 4, 5 };

I like the check on size, and that the varargs support is acting more robustly than the support for the array initializer.

Find PR with sample code at https://github.com/wbreeze/davenport/pull/15/files

Regarding https://stackoverflow.com/a/3535455/608359 from @paxdiablo, I liked it; but, felt insecure about having the number of times the initializaion pointer advances synchronized with the number of elements allocated to the array. Worst case, the initializing pointer moves beyond the allocated length. As such, the diff in the PR contains,

  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);

The int_array_init method will safely assign junk if the number of
arguments is fewer than the node_ct. The junk assignment ought to be easier
to catch and debug.

盛夏尉蓝 2024-09-22 17:09:26

如果您在程序中经常执行这些相同的任务并且想要快捷方式,最简单的解决方案可能是仅添加一个函数

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);

If you are doing these same assignments a lot in your program and want a shortcut, the most straightforward solution might be to just add a function

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;
}

and then simply call

GLfloat coordinates[8];
// ...
set_coordinates(coordinates, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f);
不打扰别人 2024-09-22 17:09:26

您可以使用 _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);

You can use _Generic and __VA_ARGS__ to write a generic array assignment macro. It doesn't need the number of arguments passed. But it's NULL terminated; Meaning you can't assign NULL aka 0. (You can put something else other than NULL which you know you won't assign).

#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);

You call GEN_ARRAY_ASSIGN_FUNC for every type and you add the type to the _Generic arguments.

And use it like this:

ARRAY_ASSIGN(coordinates, 1.f, 2.f, 3.f, 4.f);

Or if you prefer providing count rather than NULL termination:

#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);                      \
}  

And:

ARRAY_ASSIGN(coordinates, 4, 1.f, 0.f, 1.f, 0.f);
如歌彻婉言 2024-09-22 17:09:26
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;
}
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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文