Подтвердить что ты не робот

Назначить несколько значений массиву в C

Есть ли способ сделать это в сжатой форме?

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, ...};?

4b9b3361

Ответ 1

Если вы действительно назначаете значения (в отличие от инициализации), вы можете сделать это следующим образом:

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

 return coordinates; 

Ответ 2

Есть трюк, чтобы обернуть массив в структуру (которая может быть инициализирована после объявления).

т.

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

Ответ 3

Путь старой школы:

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;

Ответ 4

Точно, вы почти получили его:

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

Ответ 5

Вы можете использовать:

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

но это инициализация времени компиляции - вы не можете использовать этот метод в текущем стандарте для повторной инициализации (хотя я думаю, что есть способы сделать это в предстоящем стандарте, что может не сразу помочь вам).

Другими двумя способами, чтобы spring было умыть содержимое, если они исправлены:

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

имея в виду, что эти эллипсы (...) являются заполнителями, а не буквально вставляются в код.

Ответ 6

Если вы часто выполняете эти же задания в своей программе и хотите использовать ярлык, самым простым решением может быть просто добавить функцию

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

Ответ 7

С таким кодом:

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

Однако я решил, что мне нравится проверка размера.

Вместо того, чтобы сражаться, я пошел с инициализатором varargs:

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

Таким образом, поддержка varargs является более надежной, чем поддержка инициализатора массива.

Кто-то может сделать что-то подобное в макросе.

Найдите PR с примером кода на https://github.com/wbreeze/davenport/pull/15/files

Что касается fooobar.com/questions/214061/... от @paxdiablo, мне понравилось; но чувствовал себя неуверенно из-за того, что количество перемещений указателя инициализации синхронизировалось с количеством элементов, выделенных массиву. В худшем случае указатель инициализации выходит за пределы выделенной длины. Таким образом, разница в 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. Назначение мусора должно быть легче поймать и отладить.

Ответ 8

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