for循环判断语句中使用vector.size()发生隐式转换造成死循环问题
问题描述
今天力扣刷题中,写了一个for循环判断语句,其中判断语句用到了vector.size(),导致判断进入了死循环。问题代码如下:
int findKthLargest(vector<int>& nums, int k) {
unsigned int b=0;
int n=nums.size();
for(int i=nums.size()-1; i>=(nums.size()-k); --i){
maxIndex= i;
}
return nums[nums.size()-k];
}
测试数据:nums={2,1}, k=2
这里,for循环判断中按照逻辑理解,应该循环两次,第一次i=1
,第二次i=0
,执行第三次时i=-1
判断语句i>=(nums.size()-k)
不成立跳出循环。但奇怪就奇怪在,这里代码进入了死循环。现象如下图所示:
图中可以看到,i等于负数后,循环依然在执行。
原因分析
因为是很简单语法判断,所以出现问题我首先定位到了是nums.size()这条语句使用不当造成的。把nums.size()赋值给一个变量,再代入for循环中试一下
int findKthLargest(vector<int>& nums, int k) {
unsigned int b=0;
int n=nums.size();
for(int i=nums.size()-1; i>=(n-k); --i){
maxIndex= i;
}
return nums[nums.size()-k];
}
发现循环执行正常!!!
问题定位在了nums.size()上,查看c++11中vector.size()的原型声明,发现vector.size()的返回值是unsigned型的,猜想代码这里进入死循环是不是发生了隐式转换。当判断语句中出现signed和unsigned型后会隐式转化为unsigned型进行判断,为了验证这个猜想,我对代码进行了如下改动。定义变量b为unsigned型,并初始化为0,代入for循环中进行判断。并简化了问题模型。
int main() {
unsigned int b=0;
int a= -3;
if(a<b){
cout<<"a<b,a=-3,b=0"<<endl;
}else
cout<<"a>=b,a=-3,b=0"<<endl;
return 0;
}
执行结果:a>=b,a=-3,b=0
测试结果发现,if条件判断出现了逻辑错误,这里a先隐式转化为unsigned型再与b进行判断,判断结果就成了a>b,与真实逻辑相反。带回原问题中,nums.size()返回值是unsigned型,判断语句执行判断时,i先隐式转化成unsigned型,当i为负数时,就变成了正数,判断语句一直成立!死循环就可以理解了。。。。。