计算偶数和与奇数平均值的C语言函数异常:平均值始终返回0
问题分析与修复方案
核心问题1:可变长度数组的错误声明
代码中int Length,Tab[Length];的写法存在严重问题:声明数组时Length尚未被赋值,属于未初始化变量,用它定义数组长度会导致数组大小完全不确定。后续输入元素时极大概率发生栈内存越界,破坏其他变量(比如Moyenne)的值,这是平均值始终为0的直接诱因。
核心问题2:printf参数求值顺序的未定义行为
在printf调用中:
printf("Somme est:%d\nMoyenne est: %.2f", MoySom(Tab,&Moyenne,Length), Moyenne);
C标准并未规定函数参数的求值顺序,部分编译器会先读取Moyenne的值,再调用MoySom函数。此时Moyenne还未被函数修改,输出的是未初始化的垃圾值(若内存恰好为0就会显示0)。
核心问题3:整数除法导致平均值精度丢失
计算平均值时*Moyenne=*Moyenne/C;,*Moyenne存储的是奇数总和(整数),C是整数,两者相除会先执行整数除法,直接丢弃小数部分后再转换为float类型,导致精度错误。
额外问题:main函数返回类型不规范
标准C中main函数的返回类型必须是int,而非void,否则不符合C语言标准规范。
修复后的完整代码
#include <stdio.h> int MoySom(int Tab[], float* Moyenne, int Length) { int S = 0, C = 0; *Moyenne = 0.0f; for (int i = 0; i < Length; ++i) { if (Tab[i] % 2 == 0) { S += Tab[i]; } else { *Moyenne += Tab[i]; ++C; } } // 避免除以0的非法操作 if (C != 0) { // 强制浮点除法,保留小数精度 *Moyenne = *Moyenne / (float)C; } return S; } int main() { int Length; printf("Entrer la longeur de tableau: "); scanf("%d", &Length); // 先获取合法长度,再声明可变长度数组(C99及以后支持) int Tab[Length]; float Moyenne = 0.0f; // 初始化变量,避免未定义行为 for (int i = 0; i < Length; ++i) { printf("Entrer l'element %d: ", i); scanf("%d", &Tab[i]); } // 先调用函数修改Moyenne,再执行打印,规避求值顺序问题 int somme = MoySom(Tab, &Moyenne, Length); printf("Somme est:%d\nMoyenne est: %.2f", somme, Moyenne); return 0; }
修复说明
- 调整数组声明顺序:先通过
scanf获取Length的合法值,再声明可变长度数组Tab[Length],确保数组大小合规。 - 规避printf求值顺序问题:先调用
MoySom函数并保存结果,再执行printf,保证Moyenne已被正确修改。 - 修正除法精度:将
C强制转换为float后再做除法,确保执行浮点运算保留小数;同时增加C != 0的判断,避免除以0的非法操作。 - 初始化变量:给
Moyenne设置初始值0.0f,避免未初始化的垃圾值干扰结果。 - 修正main函数返回类型为
int,符合C语言标准。
内容的提问来源于stack exchange,提问作者Inferno
相关产品推荐
相关产品推荐

