C 在函数中使用结构的不同成员的最有效方法是什么?

C 在函数中使用结构的不同成员的最有效方法是什么?,c,struct,C,Struct,我是为一个资源非常有限的嵌入式处理器写的。我有一个捕获事件时间序列的结构,我想对不同类型的不同值使用相同的绘图函数。类似(非常精简;不要忽略未初始化的值等): #定义图1 #定义图2 结构事件{ 无符号长时间戳; int-sensorOne; 浮子传感器2; } 类型定义结构事件; 事件[10]我的事件; 无效图形传感器(字节图形类型){ for(无符号整数i=0;isensorOne; } 浮点getSensor2(常数事件) { 返回t->2; } 空图传感器(浮动(*存取器)(常数事件*)

我是为一个资源非常有限的嵌入式处理器写的。我有一个捕获事件时间序列的结构,我想对不同类型的不同值使用相同的绘图函数。类似(非常精简;不要忽略未初始化的值等):

#定义图1
#定义图2
结构事件{
无符号长时间戳;
int-sensorOne;
浮子传感器2;
}
类型定义结构事件;
事件[10]我的事件;
无效图形传感器(字节图形类型){
for(无符号整数i=0;i<9;i++){
//从序列中获取最小值
如果(我的事件[i]。??)。。。
}
}
如何让函数在结构的不同成员上运行?我可以看到用大量的
switch(graphType)
语句来实现这一点,但这相当难看。结构很可能有8到10个成员。我可以将所有这些移到一个单独的函数中,并使数据访问的每一位都调用该函数,始终返回一个浮点(对于我的图来说应该是可以的)。最后,我可以转换为C++类,它打开了其他的方法。
这些人都觉得不对。是否有更好的方法,最好是非常轻量级的方法?

您可以将所需的访问器封装在函数中,并将其传递给遍历数组并聚合结果的函数。比如说

float getSensor1(const event_t* t)
{
    return t->sensorOne;
}

float getSensor2(const event_t* t)
{
    return t->sensorTwo;
}

void GraphSensor(float (*accessor)(const event_t*)) {
    // Get minimum value from series
    float min_value = MAX_FLOAT;
    for (unsigned int i = 0; i < 9; i++) {
       float x = accessor(MyEvents + i);
       if (x < min_value)
           min_value = x;
    }
}

/* later on . . . */
GraphSensor(getSensor1);
GraphSensor(getsensor2);
float getSensor1(常量事件)
{
返回t->sensorOne;
}
浮点getSensor2(常数事件)
{
返回t->2;
}
空图传感器(浮动(*存取器)(常数事件*){
//从序列中获取最小值
浮动最小值=最大浮动;
for(无符号整数i=0;i<9;i++){
浮动x=存取器(MyEvents+i);
如果(x<最小值)
最小值=x;
}
}
/*后来*/
图形传感器(getSensor1);
图形传感器(getsensor2);

您基本上是将数据的访问与数据上的操作分离,并将其均匀化为浮动。聚合操作也可以封装到函数中。但这已经非常接近地图缩小了。:)

您可以将结构更改为一个数组,该数组可能使用所有浮点数。通过这种方式,数据处理是完全同质的

#define N_SENSORS   12
#define N_EVENTS    10 

float MyEvents [N_EVENTS] [N_SENSORS];

void GraphSensor(byte graphType)
{
    float min = 1e38;
    for (unsigned int i = 0; i < N_EVENTS; i++)
    {
       // Get minimum value from series
       if (MyEvents[i][graphType] < min)
            min = MyEvents[i][graphType];
    }
}
#定义N#u传感器12
#定义N_事件10
浮动事件[N_事件][N_传感器];
无效图形传感器(字节图形类型)
{
浮动最小值=1e38;
for(无符号整数i=0;i

可能时间戳也存在于元素0中,可能使用电子表格约定:整数部分是自1970年或1900年以来的天数,小数部分是一天中的一部分(因此中午=0.5)。

这很聪明:+1。我最初的反应是,对于数据在结构(现在是一个数组)中的位置,您会丢失人类可读的名称,但您可以使用
#define
s来命名数组中的索引以保持可读性:
MyEvents[i][SENSOR\u ONE]
而不是
MyEvents[i].sensorOne
。如果所有数据都可以共享一个公共类型,那么这种方法就有效了。如果它是异构的,那么您可能需要使用访问器函数。它肯定很聪明,我将保存它以供将来参考。如今,数据量的增加使得该项目不再具有吸引力。非常感谢。解释C上下文中的
accessor()
函数。它是在哪里定义的?(C++?)@Ryker:他没有定义它,但前两个函数就是一个很清楚的例子。在我上面的例子中,
getSensor1
getSensor2
是访问器函数(有时称为“getter”),因为它们用于访问数据,而没有透露具体的实现方式。好处是它们提供了一个接口,在这个接口后面,底层数据结构(
event\t
)可以自由更改。我看到了关于java、C++和C++的引用。不过对C来说没什么。我还注意到OP确实建议转换为C++类。所以,也许OP标签应该包括C++:好的方法。1@ryyker:
accessor
是指向
GraphSensor
函数的函数指针参数。基本上,
GraphSensor
的调用者传入函数的地址,并在需要时调用匹配的签名。我的示例的最后两行演示了这一点。
#define N_SENSORS   12
#define N_EVENTS    10 

float MyEvents [N_EVENTS] [N_SENSORS];

void GraphSensor(byte graphType)
{
    float min = 1e38;
    for (unsigned int i = 0; i < N_EVENTS; i++)
    {
       // Get minimum value from series
       if (MyEvents[i][graphType] < min)
            min = MyEvents[i][graphType];
    }
}