前言:
局部变量在参与求和等运算前必须先初始化,否则得到的值是不确定的,会产生意想不到的结果。
典型错误示范:
/**
* 函 数:将获取AD转换的值进行均值滤波
* 参 数:无
* 返 回 值:AD转换的值,范围:0~4095
*/
uint16_t ADC_AverageFilter(void)
{
volatile uint32_t adc_sum; //未初始化就开始计算,会产生意料之外的结果
for(int i=0;i<AD_NUM_MAX;i++)
adc_sum += AD_GetValue();
return adc_sum / AD_NUM_MAX; //读数据寄存器,得到AD转换的结果
}
一开始没发现异常,但是随着进一步测试,发现ADC采样超出了最大阈值4095,甚至是随机的大数字。
技术分析:
局部变量处于栈区,其数值是随机的,即当时内存中的值,必须在使用前初始化。
C语言的内存模型分为5个区:栈区、堆区、静态区、常量区、代码区。每个区存储的内容如下:
1、栈区:存放函数的参数值、局部变量等,由编译器自动分配和释放,通常在函数执行完后就释放了,其操作方式类似于数据结构中的栈。栈内存分配运算内置于CPU的指令集,效率很高,但是分配的内存量有限,比如iOS中栈区的大小是2M。
2、堆区:就是通过new、malloc、realloc分配的内存块,编译器不会负责它们的释放工作,需要用程序区释放。分配方式类似于数据结构中的链表。“内存泄漏”通常说的就是堆区。
3、静态区:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后,由系统释放。
4、常量区:常量存储在这里,不允许修改。
5、代码区:顾名思义,存放代码。
引用自:原文链接
修改之后输出参数在正常范围内波动:

总结:
程序设计中的隐藏疏漏可能会导致最终计算结果错误,需要严谨对待每一处的细节。
280

被折叠的 条评论
为什么被折叠?



