user13611213
user13611213

Reputation:

Given an array of structs, how to pass all the values for one member of the struct to a function

Given an array of structs, is there a way to pass

emp[0].hourly_wage, emp[1].hourly_wage, emp[2].hourly_wage, emp[3].hourly_wage, emp[4].hourly_wage

to a function as an array of floats?

Is it possible to pass an array of floats containing only the "hourly_wage" member and not the "OT" member... without just copying the values into a separate array of floats and then passing it to the function.

struct employee
{
    float hourly_wage;
    float OT;
};

struct employee emp[5];

Upvotes: 0

Views: 277

Answers (3)

4386427
4386427

Reputation: 44274

It's no possible.

An array requires that the array elements are located in consecutive memory (note: there may be padding between members but that's not relevant here).

In your case the memory layout of emp is like:

addrX (i.e. emp)         :  float // emp[0].hourly_wage
addrX + 1 * sizeof(float):  float // emp[0].OT
addrX + 2 * sizeof(float):  float // emp[1].hourly_wage
addrX + 3 * sizeof(float):  float // emp[1].OT
addrX + 4 * sizeof(float):  float // emp[2].hourly_wage
addrX + 5 * sizeof(float):  float // emp[2].OT
...

and there is no way to turn that into

addrY                    :  float // emp[0].hourly_wage
addrY + 1 * sizeof(float):  float // emp[1].hourly_wage
addrY + 2 * sizeof(float):  float // emp[2].hourly_wage
...

without copying from the first array to another array.

Instead the normal thing to do, is to pass the whole array of struct, i.e. pass a struct employee pointer and access whatever you need from the struct.

Upvotes: 0

H.S.
H.S.

Reputation: 12679

No, you cannot but you can create another array of pointers pointing to that one member in the array of structure and pass this array of pointers to function.

Implementation:

#include <stdio.h>
  
#define ARR_SZ 5

struct employee
{
        float hourly_wage;
        float OT;
};

void test_fun(float **arr) {
        for (int i = 0; i < ARR_SZ; ++i) {
                printf ("%f ", *arr[i]);
        }
        printf ("\n");
}

int main(void) {
        struct employee emp[ARR_SZ];

        for (int i = 0; i < ARR_SZ; ++i) {
                emp[i].hourly_wage = 2.0f;  // dummy value
                emp[i].OT = 1.0f;    // dummy value
        }

        float *hw_arr[ARR_SZ];

        for (int i = 0; i < ARR_SZ; ++i) {
                hw_arr[i] = &(emp[i].hourly_wage);
        }

        test_fun(hw_arr);

        return 0;
}

Or simply pass the array of structure to the function and access that member:

#include <stdio.h>
  
#define ARR_SZ 5

struct employee
{
        float hourly_wage;
        float OT;
};

void test_fun(struct employee *arr) {
        for (int i = 0; i < ARR_SZ; ++i) {
                printf ("%f ", arr[i].hourly_wage);
        }
        printf ("\n");
}

int main(void) {
        struct employee emp[ARR_SZ];

        for (int i = 0; i < ARR_SZ; ++i) {
                emp[i].hourly_wage = 2.0f;  // dummy value
                emp[i].OT = 1.0f;    // dummy value
        }

        test_fun(emp);

        return 0;
}

Upvotes: 1

Ken Y-N
Ken Y-N

Reputation: 15009

No.

The closest might be:

float a[10];
memcpy(a, emp, sizeof(a));

Or:

void foo(float *a) { ... }
foo((float *) emp);

But that is probably undefined behaviour as it relies on there being no packing at the end of each struct (probably none in this case, but not universally true - see the answers here), and anyway gives the data in the wrong order for you.

Upvotes: 0

Related Questions