Search code examples
carraysstructsizeofunions

Access struct members as if they are a single array?


I have two structures, with values that should compute a pondered average, like this simplified version:

typedef struct
{
  int v_move, v_read, v_suck, v_flush, v_nop, v_call;
} values;

typedef struct
{
  int qtt_move, qtt_read, qtt_suck, qtd_flush, qtd_nop, qtt_call;
} quantities;

And then I use them to calculate:

average = v_move*qtt_move + v_read*qtt_read + v_suck*qtt_suck + v_flush*qtd_flush + v_nop*qtd_nop + v_call*qtt_call;

Every now and them I need to include another variable. Now, for instance, I need to include v_clean and qtt_clean. I can't change the structures to arrays:

typedef struct
{
    int v[6];
} values;
typedef struct
{
    int qtt[6];
} quantities;

That would simplify a lot my work, but they are part of an API that need the variable names to be clear.

So, I'm looking for a way to access the members of that structures, maybe using sizeof(), so I can treat them as an array, but still keep the API unchangeable. It is guaranteed that all values are int, but I can't guarantee the size of an int.

Writing the question came to my mind... Can a union do the job? Is there another clever way to automatize the task of adding another member?

Thanks, Beco


Solution

  • If all members a guaranteed to be of type int you can use a pointer to int and increment it:

    int *value = &(values.v_move);
    int *quantity = &(quantities.qtt_move);
    int i;
    average = 0;
    // although it should work, a good practice many times IMHO is to add a null as the last member in struct and change the condition to quantity[i] != null.
    for (i = 0; i < sizeof(quantities) / sizeof(*quantity); i++)
        average += values[i] * quantity[i];
    

    (Since the order of members in a struct is guaranteed to be as declared)