Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing struct containing arrays

I have a struct in C, which members are float arrays. I want to initialize it during compile time like this:

typedef struct curve {                                                                                         
    float *xs;                                                                                             
    float *ys;                                                                                             
    int    n;                                                                                              
} curve;                                                                                                       

curve mycurve1 = {                                                                                             
    {1, 2, 3},                                                                                                     
    {4, 2, 9},                                                                                                     
    3                                                                                                              
};

curve mycurve2 = {
    {1, 2, 3, 4},
    {0, 0.3, 0.9, 1.5},
    4
};                                                                                                              

But I get compile errors.

One possible solution might be to use arrays and not pointers in the struct. This is the accepted answer of a very similar question from here: https://stackoverflow.com/a/17250527/1291302, but the problem with that approach is that I don't know the array size at typedef time. Not only that, I might want to initialize another, bigger curve.

Another approach might be with malloc, but I find that overkill, because I know the array size at compile time and I don't need it to change during run-time.

I don't know another approaches, which might be useful. Maybe casting array to pointer?? - I don't really know how I would approach that.

like image 920
JonnyRobbie Avatar asked Feb 12 '20 19:02

JonnyRobbie


People also ask

How do you initialize a struct array?

If you have multiple fields in your struct (for example, an int age ), you can initialize all of them at once using the following: my_data data[] = { [3]. name = "Mike", [2]. age = 40, [1].

Can you have an array in a struct?

A structure may contain elements of different data types – int, char, float, double, etc. It may also contain an array as its member. Such an array is called an array within a structure.

Can you initialize in struct?

You can also create and initialize a struct with a struct literal. An element list that contains keys does not need to have an element for each struct field. Omitted fields get the zero value for that field.

What is struct initialization?

An initializer for a structure is a brace-enclosed comma-separated list of values, and for a union, a brace-enclosed single value. The initializer is preceded by an equal sign ( = ).


2 Answers

You may not initialize a scalar object like a pointer with a braced list that contains several initializers.

But you can use compound literals.

Here is a demonstrative program.

#include <stdio.h>

typedef struct curve {                                                                                         
    float *xs;                                                                                             
    float *ys;                                                                                             
    int    n;                                                                                              
} curve;                                                                                                       

int main(void) 
{
    curve mycurve1 = 
    {                                                                                             
        ( float[] ){ 1,  2, 3 },                                                                                                     
        ( float[] ){ 4,  2, 9 },                                                                                                     
        3
    };

    curve mycurve2 = 
    {
        ( float[] ){ 1, 2, 3, 4 },
        ( float[] ){ 0, 0.3, 0.9, 1.5 },
        4
    };

    for ( int i = 0; i < mycurve1.n; i++ )
    {
        printf( "%.1f ", mycurve1.xs[i] );
    }
    putchar( '\n' );

    for ( int i = 0; i < mycurve2.n; i++ )
    {
        printf( "%.1f ", mycurve2.ys[i] );
    }
    putchar( '\n' );

    return 0;
}

Its output is

1.0 2.0 3.0 
0.0 0.3 0.9 1.5 
like image 79
Vlad from Moscow Avatar answered Sep 28 '22 06:09

Vlad from Moscow


A suggested take on @Vlad from Moscow good answer.

Use const when constant

because I know the array size at compile time and I don't need it to change during run-time.

Consider const curve mycurve1 = .... This allows for select optimizations, identifies mis-use and allows passing &mycurve1 to bar(const curve *). Also with const float [... allows passing mycurve1.xs to foo(const float *).

Avoid magic numbers

#define CURVE1_N 3
const curve mycurve1 = {
  ( const float[CURVE1_N] ){ 1,  2, 3 },
  ( const float[CURVE1_N] ){ 4,  2, 9 },  
  CURVE1_N
};
like image 29
chux - Reinstate Monica Avatar answered Sep 28 '22 04:09

chux - Reinstate Monica