Инициализация структуры, содержащей массивы

У меня есть структура в C, члены которой являются массивами с плавающей точкой. Я хочу инициализировать его во время компиляции следующим образом:

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
};                                                                                                              

Но я получаю ошибки компиляции.

Одним из возможных решений может быть использование массивов, а не указателей в структуре. Это принятый ответ на очень похожий вопрос отсюда: https://stackoverflow.com/a/17250527/1291302 , но проблема этого подхода в том, что я не знаю размера массива во время определения типа. Не только это, я мог бы хотеть инициализировать другую, большую кривую.

Другой подход может быть с malloc, но я нахожу это излишним, потому что я знаю размер массива во время компиляции и мне не нужно его менять во время выполнения.

Я не знаю других подходов, которые могут быть полезны. Может быть, приведение массива к указателю ?? - Я не знаю, как бы я подошел к этому.

Всего 2 ответа


Вы не можете инициализировать скалярный объект, например, указатель с фигурным списком, который содержит несколько инициализаторов.

Но вы можете использовать составные литералы.

Вот демонстрационная программа.

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

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

    return 0;
}

Его вывод

1.0 2.0 3.0 
0.0 0.3 0.9 1.5 

Предлагаемый вариант @Vlad из Москвы - хороший ответ.

Используйте const когда константа

потому что я знаю размер массива во время компиляции, и мне не нужно его менять во время выполнения.

Рассмотрим постоянную const curve mycurve1 = ... Это позволяет выбирать оптимизацию, выявляет неправильное использование и позволяет передавать &mycurve1 на bar(const curve *) . Также с помощью const float [... позволяет передавать mycurve1.xs в foo(const float *) .

Избегайте магических чисел

#define CURVE1_N 3
const curve mycurve1 = {
  ( const float[CURVE1_N] ){ 1,  2, 3 },
  ( const float[CURVE1_N] ){ 4,  2, 9 },  
  CURVE1_N
};

Есть идеи?

10000