for循环内置多条件与循环体if判断实现数组元素非零减索引的效果差异疑问
两种非零判断位置导致数组处理结果不同的问题
基础场景说明
- 结果数组
res的初始值为[3, 2, 3, 5, 5, 6, 0, 8, 9, 0] - 实现需求:对数组中所有非零元素,将其值减去元素对应的索引值
两种实现的代码与运行结果
第一种实现:将非零判断写在for循环的条件区
for(int i=0;i<res.length && res[i]!=0;i++) res[i] =res[i]-i;
该写法得到的输出结果为:res = [3,1,1,2,1,1,0,8,9,0]
第二种实现:将非零判断写在循环体的if语句中
for(int i=0;i<res.length;i++){ if(res[i]!=0) res[i] =res[i]-i; }
该写法得到的输出结果为:res = [3,1,1,2,1,1,0,1,1,0]
核心疑问
为什么将判断条件放在for循环的条件区,和放在循环体的if逻辑分支中,会产生截然不同的运行效果?
差异原因拆解
两种写法的逻辑本质完全不同,不存在等价性:
- for循环的条件段是循环终止判定:只要这里的条件返回假,循环会立刻中断,后续所有的数组元素都不会被遍历处理
- 循环体内的if是遍历过程中的分支选择:不管当前元素是否满足if的判断要求,循环本身都会持续向后执行,直到遍历完整个数组长度
第一种写法的执行过程
- 循环从索引0开始,逐次校验终止条件:索引值小于数组长度,且当前索引位置的数组值不等于0,两个条件同时满足才会执行当前位置的赋值,再将索引自增
- 当索引增长到6时,校验终止条件:当前位置
res[6]的原始值就是0,res[i]!=0的判定返回假,循环直接终止 - 索引7、8、9位置的元素完全没有进入循环体的执行范围,全部保留初始值,最终输出和实际运行结果一致
第二种写法的执行过程
- 循环的终止条件只有“索引小于数组长度”,会完整遍历数组从0到9的所有索引位置,不会因为某个位置值为0就提前中断
- 遇到值为0的元素时,只是跳过当前位置的赋值操作,循环会继续向后执行后续位置的遍历
- 索引7、8位置的非零元素会正常执行“值减去对应索引”的计算:
res[7] = 8-7 =1、res[8] =9-8=1,最终输出和实际运行结果一致
内容的提问来源于stack exchange,提问作者Abhay Kumar
相关产品推荐
相关产品推荐

