编写C语言移动平均代码出现报错,请求排查原因
先拆解你代码里的几个核心问题,这些都是导致运行崩溃或逻辑异常的根源:
未初始化变量
n和k
你定义了int n, k;但直接用在malloc(sizeof(int)*n)和循环里,这两个变量此时是随机的垃圾值。用随机大小分配内存大概率会导致分配失败,后续数组访问也会触发越界,直接引发程序崩溃。必须先从用户输入获取n(数据总长度)和k(移动窗口大小)。硬编码窗口大小,逻辑不匹配
第二个循环里你写了sum=sum-a[i-3]+a[i];和avg=sum/3+0.5;,但你的变量是k,这里应该用k代替固定的3——否则当k不是3时,逻辑完全错误,还会导致数组越界(比如k=2时访问a[i-3])。四舍五入实现错误
avg是整数类型,sum/(i+1)+0.5这种写法无效:整数除法sum/(i+1)已经是截断后的整数,加0.5后赋值给int会直接丢掉小数部分,根本达不到四舍五入的效果。正确的整数四舍五入应该用(sum + 窗口大小/2) / 窗口大小,比如窗口为i+1时,就是(sum + (i+1)/2) / (i+1)。错误处理不完整
当malloc失败时,你只打印了"error"但程序还会继续执行,此时a或x是NULL,后续的scanf、数组访问都会触发非法内存访问,直接崩溃。应该在malloc失败后用exit(1);终止程序,避免后续错误操作。内存泄漏
你用malloc分配了a和x,但代码最后没有调用free(a); free(x);释放内存,长期运行会导致内存泄漏。代码截断
你最后写的fr...应该是free没写完,这也是导致编译或运行错误的原因之一。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> int main() { int *a, *x; int n, k; int i; int sum = 0, avg = 0; // 先获取数据长度n和窗口大小k printf("请输入数据长度n和移动窗口大小k:"); scanf("%d %d", &n, &k); // 检查k的合法性 if (k <= 0 || k > n) { printf("窗口大小k必须大于0且小于等于n\n"); return 1; } a = (int*)malloc(sizeof(int)*n); if(a == NULL) { printf("内存分配失败\n"); exit(1); } x = (int*)malloc(sizeof(int)*n); if(x == NULL) { printf("内存分配失败\n"); free(a); // 已分配的内存要提前释放 exit(1); } // 输入数据 printf("请输入%d个整数:", n); for(i = 0; i < n; i++) { scanf("%d", &a[i]); } // 计算前k个元素的逐步平均(窗口从1到k) sum = 0; for(i = 0; i < k; i++) { sum += a[i]; // 整数四舍五入:sum加上窗口大小的一半再除以窗口大小 avg = (sum + (i+1)/2) / (i+1); x[i] = avg; } // 计算k之后的移动平均 for(i = k; i < n; i++) { sum = sum - a[i - k] + a[i]; avg = (sum + k/2) / k; x[i] = avg; } // 输出结果,用空格分隔更易读 printf("移动平均结果:"); for(i = 0; i < n; i++) { printf("%d ", x[i]); } printf("\n"); // 释放内存 free(a); free(x); return 0; }
你可以试试这个修正后的版本,应该能解决你遇到的报错问题,同时逻辑也更严谨。
内容的提问来源于stack exchange,提问作者Jiho Park

