曾经,写过如下代码片段,用于求最大值(最小值):
for (i = 0; i < N; i++)
{
if (Data[i] > max)
{
max = Data[i];
}
if (Data[i] < min)
{
min = Data[i];
}
}
一位专家(Frank)看到了,告诉我说,如果Data[i]大于max,就不需要再和min进行比较了,第二个if应该改为else if,这样可以少比较一次。从此我牢记在心。
可是,最近我写出类似的代码,在调试的时候发现,这个原则也不是绝对的,还需要考虑上下文。
代码段如下:
uiTempNum = DB_GetUint16(VID_TEMP_NUM);
siMax = -1000;
siMin = 1000;
uiMaxPosi = uiMinPosi = 0;
// 找出最高,最低
for (i = 0; i < uiTempNum; i++)
{
siTemp = DB_GetInt16(VID_SYS_NTC_TEMP01 + i);
if ((siTemp < -380) || (siTemp > 1000))
{
continue;
}
if (siTemp > siMax)
{
siMax = siTemp;
uiMaxPosi = i + 1;
}
else if (siTemp < siMin)
{
siMin = siTemp;
uiMinPosi = i + 1;
}
uiSum += siTemp;
uiValidTempNum++;
}
为了测试功能逻辑,不依赖于硬件,我在初始化时将10路温度分别设为21~30度,却发现最小温度没有找出来!
单步跟踪一下,很容易找到问题的原因:每一次都进入if分支,而没有机会执行else if。
根本原因在于,Frank所说实际上隐含着一个前提,即max必定大于min,所以大于max就必定不会小于min。而我这里在for循环之前赋初值时就打破了这一前提条件。具体问题还是需要具体分析啊。
解决措施就是,去掉else,每次都与max和min进行判断。