Assign multiple values to array in C

前端 未结 8 1220
无人共我
无人共我 2020-12-01 14:01

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         


        
相关标签:
8条回答
  • 2020-12-01 14:13

    With code 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
    

    The compiler on my dev box was 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 };
    

    however, I decided that I like the check on size.

    Rather than fighting, I went with a varargs initializer:

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

    As such, the varargs support is more robust than the support for the array initializer.

    Someone might be able to do something like this in a macro.

    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.

    0 讨论(0)
  • 2020-12-01 14:16

    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.

    0 讨论(0)
  • 2020-12-01 14:17
    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;
    }
    
    0 讨论(0)
  • 2020-12-01 14:27

    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);
    
    0 讨论(0)
  • 2020-12-01 14:28

    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, ... } };
    
    0 讨论(0)
  • 2020-12-01 14:31

    Exactly, you nearly got it:

    GLfloat coordinates[8] = {1.0f, ..., 0.0f};
    
    0 讨论(0)
提交回复
热议问题