【问题标题】:Casting data array to compatible struct将数据数组转换为兼容的结构
【发布时间】:2015-07-26 01:01:21
【问题描述】:

我的代码从我无法控制的地方以floats 的长列表形式接收数据。

这些数字被分配到不同的功能

void myfunc(struct floatstruct* fs);

采用以下形式的结构:

struct floatstruct
{
    float a;
    float b;
    float c;
};

你明白了。

我想知道是否有一种方法可以安全地将浮点数组转换为floatstruct 以将数据直接传递给myfunc。如有必要,我可以将对齐属性添加到floatstruct

期望行为示例:

struct mystruct1
{
    float a;
    float b;
    float c;
};

struct mystruct2
{
    float x;
    float y;
};

extern void myfunc1(mystruct1*);
extern void myfunc2(mystruct2*);

void process_data(float* numbers)
{
    myfunc1((struct mystruct1*)numbers);
    myfunc2((struct mystruct2*)(numbers + 3));
}

理想的解决方案肯定是改变系统。但我正在寻找给定参数内的解决方案。

【问题讨论】:

  • 您只需将 arr[] 中每个索引的值设置为 struct 中的浮点数之一...有什么困惑?
  • 这当然是目前所做的。但是有一些新的性能限制。由于数据已经以我需要的方式(或多或少)在内存中,我不想再次复制它。
  • 好吧,你不能从浮点数转换为结构体,即使它包含浮点数,它也不能那样工作
  • 还有一件事,因为结构成员的打包和对齐取决于实现,但数组成员在内存中是连续的,请确保告诉编译器紧密打包结构对象(例如,使用 @ GCC 中的 987654328@ 属性)。

标签: c arrays struct casting memory-alignment


【解决方案1】:

考虑到您的特殊要求,我会这样做:(我这么说是因为这里或那里的 3 个新花车实际上不会产生明显的差异,除非您打算在 arduino 或手机上使用它,或者如果您打算拥有数十个成千上万...)

无论如何:

    struct floatstruct
{
    float (*a[3]);
};



{
    int i;
    struct floatstruct aStruct;
    struct floatstruct bStruct;
    float *num = numbers;
    for (i = 0; i < 6; i++) {
        if (i < 3)
            aStruct.a[i] = num;
        else 
            bStruct.a[i-3] = num;
        num++;
    }

    myfunc1(&aStruct);
    myfunc2(&bStruct);
}

【讨论】:

    【解决方案2】:

    Union 可能是您所需要的:

    #pragma pack(sizeof(float))
    struct mystruct1
    {
        float a;
        float b;
        float c;
    };
    
    struct mystruct2
    {
        float x;
        float y;
    };
    #pragma pack()
    
    typedef union
    {
       mystruct1 struct1;
       mystruct2 struct2;
    }structsUnion;
    
    void myfunc1(structsUnion* values)
    {
        values->struct1.a; // to access members
    }
    void myfunc2(structsUnion* values)
    {
        values->struct2.x; // to access members
    }
    
    void process_data(float* numbers)
    {
        myfunc1((structsUnion*)(numbers));
        myfunc2((structsUnion*)(numbers));
    }
    

    【讨论】:

    • 联合只允许您一次在内存中拥有一项。即使您使用带有 2 个浮点数的结构并调用需要 3 个浮点数的结构,您的方法也适用于任一函数。换句话说,您将调用一个未初始化的变量,并得到垃圾
    • 我知道。好的。可能我误解了 OP 问题。
    猜你喜欢
    • 1970-01-01
    • 2015-09-08
    • 2021-10-03
    • 2020-11-30
    • 1970-01-01
    • 2015-06-22
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多