V. Winters
V. Winters

Reputation: 9

How to pass an array of structures to a function by reference in C?

This code is similar to what I am attempting to do, however I am getting errors saying that I am passing incompatable types

 #include <stdio.h>

struct numbers{
    int num;
};

void fillArray(struct numbers* a[]);

int main(void)
{
    struct numbers array[4]; 

    fillArray(&array);

    for(int i = 0; i < 4; i++)
    {
        printf("%d", array[i].num);
    }

}

void fillArray(struct numbers* a[])
{
    for(int i = 0; i < 4; i++)
    {
        a[i]->num = i;
    }
}

Upvotes: 0

Views: 76

Answers (4)

Vlad from Moscow
Vlad from Moscow

Reputation: 310990

The function parameter

void fillArray(struct numbers* a[]);

is adjusted to

void fillArray(struct numbers ** a);

On the other hand the type of the argument in this call

fillArray(&array);

is struct numbers( * )[4]. The types struct numbers ** and struct numbers ( * )[4] are incompatible.

There is no need to pass a pointer to the array because elements of the array are already passed indirectly if you will pass just the array that is implicitly converted to pointer to its first element.

So what you need is to declare and define the function like

void fillArray( struct numbers a[] )
// or
// void fillArray( struct numbers *a )
{
    for(int i = 0; i < 4; i++)
    {
        a[i].num = i;
    }
}

and call it like

fillArray( array );

Take into account that the function depends on magic number 4. It is better to define the function such a way that it could deal with arrays of various numbers of elements.

So I would define the function like

void fillArray( struct numbers a[], size_t n )
// or
// void fillArray( struct numbers *a, size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        a[i].num = i;
    }
}

and call it like

fillArray( array, 4 );

Here is demonstrated how the program can look in whole

#include <stdio.h>

struct numbers
{
    int num;
};

void fillArray( struct numbers a[], size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        a[i].num = i;
    }
}

#define N   4

int main(void) 
{
    struct numbers array[N]; 

    fillArray( array, N );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", array[i].num );
    }

    putchar( '\n' );

    return 0;
}

Its output is

0 1 2 3 

To use an array with a different number of elements it is enough to change the value of the macro name N. Thus the program and its function do not depend on the magic number 4.

Upvotes: 2

LPs
LPs

Reputation: 16223

Your function wants an array of pointers, but you have a single array, so

void fillArray(struct numbers* a);

or

void fillArray(struct numbers a[]);

Moreover using a[i] you are already dereferencing the pointer, so you need . not -> operator.

#include <stdio.h>

struct numbers
{
    int num;
};

void fillArray(struct numbers *a);

int main(void)
{
    struct numbers array[4];

    fillArray(array);

    for (int i = 0; i < 4; i++)
    {
        printf("%d", array[i].num);
    }

    printf("\n");

}

void fillArray(struct numbers *a)
{
    for (int i = 0; i < 4; i++)
    {
        a[i].num = i;
    }
}

Finally using array decays to pointer to first item of array, so

fillArray(&array);

must be

fillArray(array);

or

fillArray(&array[0]);

Lastly you should pass size of array to your function, instead of using fixed numbers. You can do it using pointer and size

#include <stdio.h>

struct numbers
{
    int num;
};

void fillArray(size_t size, struct numbers *a);

int main(void)
{
    struct numbers array[4];

    fillArray(sizeof(array)/sizeof(array[0]), array);

    for (int i = 0; i < 4; i++)
    {
        printf("%d", array[i].num);
    }

    printf("\n");

}

void fillArray(size_t size, struct numbers *a)
{
    for (size_t i = 0; i < size; i++)
    {
        a[i].num = i;
    }
}

Or using VLAs

#include <stdio.h>

struct numbers
{
    int num;
};

void fillArray(size_t size, struct numbers a[size]);

int main(void)
{
    struct numbers array[4];

    fillArray(sizeof(array)/sizeof(array[0]), array);

    for (int i = 0; i < 4; i++)
    {
        printf("%d", array[i].num);
    }

    printf("\n");

}

void fillArray(size_t size, struct numbers a[size])
{
    for (size_t i = 0; i < size; i++)
    {
        a[i].num = i;
    }
}

Upvotes: 1

Jabberwocky
Jabberwocky

Reputation: 50775

You probably want this:

#include <stdio.h>

struct numbers {
    int num;
};

void fillArray(struct numbers a[]);

int main(void)
{
    struct numbers array[4];

    fillArray(array);

    for (int i = 0; i < 4; i++)
    {
        printf("%d\n", array[i].num);
    }

}

void fillArray(struct numbers a[])
{
    for (int i = 0; i < 4; i++)
    {
        a[i].num = i;
    }
}

Upvotes: 1

Paul Ogilvie
Paul Ogilvie

Reputation: 25286

It is sufficient to only mention the array name. The compiler will transform it into a pointer to the first element.

So instead of

 fillArray(&array);

you write

 fillArray(array);

Though this answers your question, of course the function being called must have a compatible definition, which in your case is not so.

Upvotes: -1

Related Questions