wake-up-neo.com

Weisen Sie dem Array in C mehrere Werte zu

Gibt es eine Möglichkeit, dies in komprimierter Form zu tun?

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;

So etwas wie coordinates = {1.0f, ...};?

27
UnstableFractal

Wenn Sie wirklich zuweisen Werte (im Gegensatz zu initialisieren), können Sie dies folgendermaßen tun:

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

 return coordinates; 
23
James Curran

Der Weg der alten Schule:

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;
10
Pavel Minaev

Es gibt einen Trick, um das Array in eine Struktur zu packen (die nach der Deklaration initialisiert werden kann).

dh.

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

Genau, du hast es fast geschafft:

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

Sie können verwenden:

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

dies ist jedoch eine Initialisierung zur Kompilierzeit - Sie können diese Methode im aktuellen Standard nicht zur Neuinitialisierung verwenden (obwohl ich denke, dass es Möglichkeiten gibt, dies im kommenden Standard zu tun, was Ihnen möglicherweise nicht sofort weiterhilft).

Die anderen zwei Möglichkeiten, die Ihnen einfallen, sind das blattern des Inhalts, wenn sie behoben sind:

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

oder eine Funktion bereitstellen, die ohnehin wie Ihr Initialisierungscode aussieht:

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

beachten Sie, dass diese Ellipsen (...) Platzhalter sind, nicht Dinge, die Sie buchstäblich in den Code einfügen.

3
paxdiablo

Wenn Sie häufig dieselben Aufgaben in Ihrem Programm ausführen und eine Verknüpfung wünschen, ist es am einfachsten, eine Funktion hinzuzufügen

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

und dann einfach anrufen

GLfloat coordinates[8];
// ...
set_coordinates(coordinates, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f);
0
dpi

Mit Code wie diesem:

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

Und in der configure.ac

AC_PROG_CC_C99

Der Compiler auf meiner Dev-Box war glücklich. Der Compiler auf dem Server hat sich beschwert mit:

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

und

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

für jedes Element

Es klagt überhaupt nicht darüber, zum Beispiel:

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

ich entschied jedoch, dass mir der Größencheck gefällt.

Anstatt zu kämpfen, habe ich mich für einen varargs-Initialisierer entschieden:

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

genannt wie,

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

Daher ist die varargs-Unterstützung robuster als die Unterstützung für den Array-Initialisierer.

Jemand ist möglicherweise in der Lage, so etwas in einem Makro auszuführen.

Finden Sie PR mit Beispielcode unter https://github.com/wbreeze/davenport/pull/15/files

In Bezug auf https://stackoverflow.com/a/3535455/608359 von @paxdiablo hat es mir gefallen; Wir fühlten uns jedoch unsicher, wie oft der Initialisierungszeiger mit der Anzahl der dem Array zugewiesenen Elemente synchronisiert wurde. Im schlimmsten Fall springt der Initialisierungszeiger über die zugewiesene Länge hinaus. Als solches enthält der Unterschied in der 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);

Das int_array_init Methode wird sicher Junk zuweisen, wenn die Anzahl der Argumente geringer als die von node_ct ist. Die Junk-Zuweisung sollte einfacher zu fangen und zu debuggen sein.

0
Douglas Lovell