You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何传递含二维数组的结构体至函数并实现滑动平均计算?

实现滑动平均函数与结构体传参方案

首先,先确认传参逻辑的正确性:你的STATS结构体包含多个大尺寸二维数组(比如float X[80][2]),如果直接按值传递结构体,会触发整个结构体的内存拷贝,既浪费内存又降低性能。正确的做法是传递结构体指针,这样函数内部可以直接操作原结构体的数据,效率更高。

接下来,针对你给出的滑动平均公式 Average = Average(Prev) + (ValueToAverage/n) - (Average(Prev)/n),我们会严格按照这个公式实现(其实它可以等价简化为 Average = Average(Prev) * (n-1)/n + ValueToAverage/n,但我们保留你指定的原始逻辑)。

假设前提说明

根据你的结构体设计,这里先明确字段的作用(如果实际语义不同,可以随时调整):

  • X[80][2]、Y[80][2]、Z[80][2]:每个[i][0]存储第i组的当前滑动平均值,[i][1]存储新加入的待平均样本值
  • T[80][2]:同理,因为是int类型,计算时需要做浮点转换再转回整数
  • K[80]:存储第i组的滑动窗口大小n(即参与平均的样本数量)

完整函数实现

#include <stdio.h>

// 你定义的结构体
typedef struct{ 
    float X[80][2]; 
    float Y[80][2]; 
    float Z[80][2]; 
    int T[80][2]; 
    int K[80]; 
} STATS;

// 滑动平均函数:传递结构体指针,避免大内存拷贝
void MovingAverage(STATS *stats) {
    // 遍历每组数据(0到79)
    for (int i = 0; i < 80; i++) {
        int n = stats->K[i];
        // 窗口大小不能为0,避免除零错误
        if (n <= 0) {
            fprintf(stderr, "Warning: Window size K[%d] is invalid (≤0)\n", i);
            continue;
        }

        // 更新X组的滑动平均值
        float prevAvgX = stats->X[i][0];
        float newValX = stats->X[i][1];
        stats->X[i][0] = prevAvgX + (newValX / n) - (prevAvgX / n);

        // 更新Y组的滑动平均值
        float prevAvgY = stats->Y[i][0];
        float newValY = stats->Y[i][1];
        stats->Y[i][0] = prevAvgY + (newValY / n) - (prevAvgY / n);

        // 更新Z组的滑动平均值
        float prevAvgZ = stats->Z[i][0];
        float newValZ = stats->Z[i][1];
        stats->Z[i][0] = prevAvgZ + (newValZ / n) - (prevAvgZ / n);

        // 更新T组的滑动平均值(int类型需处理类型转换)
        int prevAvgT = stats->T[i][0];
        int newValT = stats->T[i][1];
        // 先按浮点计算,再四舍五入取整(也可根据需求改为直接截断)
        float newAvgT = (float)prevAvgT + ((float)newValT / n) - ((float)prevAvgT / n);
        stats->T[i][0] = (int)(newAvgT + 0.5f);
    }
}

// 测试示例
int main() {
    STATS myStats = {0};
    // 初始化:第0组窗口大小n=5,初始平均值为10,新样本为15
    myStats.K[0] = 5;
    myStats.X[0][0] = 10.0f;
    myStats.X[0][1] = 15.0f;

    MovingAverage(&myStats);
    printf("Updated X[0][0] average: %.2f\n", myStats.X[0][0]);
    // 输出应为11.00:10 + (15/5) - (10/5) = 10 +3 -2=11

    return 0;
}

关键细节说明

  1. 传参逻辑:使用STATS *stats指针传递,函数内部通过->访问结构体成员,直接修改原结构体的数据,彻底避免了大数组的拷贝开销。
  2. 异常保护:增加了对K[i] <=0的判断,防止运行时出现除零崩溃的情况。
  3. 整数类型处理:针对T数组的int类型,先转换为浮点完成滑动平均计算,再根据需求做取整处理(示例用了四舍五入,你也可以改成直接截断)。
  4. 公式严格匹配:完全按照你给定的公式编写逻辑,没有做简化替换,确保和你的需求完全一致。

如果你的结构体字段实际用途和我假设的不同(比如X是存储历史样本的数组),可以告诉我具体的语义,我再调整实现逻辑。

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:00:50