C结构不同大小 [英] C same structure different size

查看:200
本文介绍了C结构不同大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与此相关:
c在不同大小的结构体中定义数组



但是,我不想使用动态分配(嵌入式目标)。




  • 问题回顾:



C 想要有两个相同结构的版本,每个版本的静态数组的大小不同。
这两个结构将由相同的函数通过指针参数使用。

  typedef struct {
short isLarge; //初始化时设置0
short array [SIZE_A];
//更多数组
} doc_t;

typedef struct {
short isLarge; //初始化时设置1
short array [SIZE_B];
//更多数组
} doc_large_t;

void function(doc_t * document){
if(document-> isLarge){
//将文档更改为doc_large_t * [1]
}
// doc_t和doc_large_t
的通用代码




  • 问题:



(1)上述描述需要一种方式来动态地将指针doc_t *指针转换为doc_large_t *文档[1 ]。那可能吗 ?如何?



(2)我提出的另一个解决方案是为两个结构都有一个公共的头部数据部分,不仅包括isLarge标志,还包括指向以下静态数组。 (3)另外,你可以使用一个很好的技巧或者工作环境吗?



更多上下文:


我的应用程序是嵌入式MCU的路径查找。



我有几何对象,如多边形。多边形可以描述简单的矩形障碍物,以及更复杂的形状(如可访问区域)。



复合多边形可以有大量的顶点,但是是小的数量。简单的多边形很常见。



两者都使用相同的算法。
我提前知道哪个多边形将需要更多的顶点。



我想要做的是优化工作内存,使其适合MCU。 (即小形状得到小数组;复数形式获得大数组)

解决方案

与您在问题中提到的想法相似指针数组),但只​​有一个单指针:

  typedef struct 
{
short array [SIZE_B - SIZE_A];
//更多数组...
}扩展;
typedef struct
{
short array [SIZE_A];
//更多数组(所有小的!)
扩展* extraData;
} doc_t;

如果extraData为NULL,则您有一个小的多边形,否则,您在结构中找到附加数据引用。承认,迭代大多边形的所有值都会有点讨厌...



如果您可以使用每个对象的预定义大小的全局数组类型(如Dominic Gibson所提出的 - 一个很好的命题,顺便说一下),你可以用一个函数替换它的isLarge标志:

  int isLarge(void * ptr)
{
return
(uintptr_t)globalLargeArray< =(uintptr_t)ptr
&&
(uintptr_t)ptr < (uintptr_t)globalLargeArray + sizeof(globalLargeArray);
}

当然,所有多边形(在上述情况下:至少大的)将不得不生活在这个数组中,使其工作。如果您至少创建一个动态或其他地方(堆栈,另一个全局变量) - 我们是... ...


My question is related to this one : c define arrays in struct with different sizes

However, I do NOT want to use dynamic allocation (embedded target).

  • Problem recap :

In C, I want to have two versions of the same structure, each one with a different size for its static arrays. Both the structures will be used by the same functions through pointer parameter.

    typedef struct {
        short isLarge;         //set 0 at initialization
        short array[SIZE_A];
        //more arrays
    } doc_t;

    typedef struct {
        short isLarge;         //set 1 at initialization
        short array[SIZE_B];
        //more arrays
    } doc_large_t;

    void function( doc_t* document ) {
        if ( document->isLarge ) {
             //change document into doc_large_t* [1]
        } 
        //common code for both doc_t and doc_large_t
    }

  • Questions :

(1) The above description needs a way to dynamically cast the pointer doc_t* pointer to doc_large_t* document [1]. Is that possible ? How ?

(2) An other solution i came with is to have a common header data part for both structure, including not only the isLarge flag, but also the pointers to the following static arrays. How ugly is that ?

(3) Also, do you have a good trick or workarround I could use ?

EDIT :

  • More context :

My application is a path finding on an embedded MCU.

I have geometrical objects, like polygons. Polygons can describe simple rectangular obstacles, as well as more complex shapes (such as the accessible area).

Complex polygons can have a huge amount of vertices, but are in small quantity. Simple polygons are very common.

Both will use the same algorithms. I know in advance which polygon will need more vertices.

What I am trying to do is to optimize working memory to make it fit into the MCU. (i.e. small shapes get small arrays; complex ones get large arrays)

解决方案

Idea similar to what you mentioned in your question already (pointers to arrays), but with only one single pointer:

typedef struct
{
     short array[SIZE_B - SIZE_A];
     // more arrays alike...
} Extension;
typedef struct
{
    short array[SIZE_A];
    //more arrays (all the small ones!)
    Extension* extraData;
} doc_t;

If extraData is NULL, you have a small polygone, otherwise, you find the additional data in the struct referenced. Admitted, iterating over all values for large polygons gets a little nasty...

If you can use global arrays of predefined size for each object type (as Dominic Gibson proposed - a good proposition, by the way), you could spare the isLarge flag by replacing it with a function:

int isLarge(void* ptr)
{
    return
        (uintptr_t)globalLargeArray <= (uintptr_t)ptr
        &&
        (uintptr_t)ptr < (uintptr_t)globalLargeArray + sizeof(globalLargeArray);
}

Of course, all polygons (in above case: the large ones at least) would have to live in this array to make it work. If you create at least one dynamically or otherwise elsewhere (stack, another global variable) - we are out...

这篇关于C结构不同大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆