C++ for循环内外max/min变量值不一致问题排查
问题说明
我是C++初学者,想要编写程序实现数组中最大值与最小值互换的功能,初始编写代码如下:
#include<iostream> using namespace std; int main(){ int num, arr[200],max,min,max_pos,min_pos; cout <<"enter array size: "; cin >> num; for (int i=0; i<num; i++){ cout<<"Enter a value in array position "<<i<<" : "; cin>>arr[i]; } for(int i=1, max=arr[0], min=arr[0]; i<num; i++){ if(arr[i]>arr[i-1] && arr[i]>max){ max = arr[i]; max_pos = i; } if(arr[i]<arr[i-1] && arr[i]<min){ min = arr[i]; min_pos = i; } cout<<"max_in "<<max<<"||"<<"min_in "<<min<<endl; } cout<<"max_out "<<max<<"||"<<"min_out "<<min<<endl; // arr[min_pos] = max; // arr[max_pos] = min; // cout<<"max: "<<arr[min_pos]<<" || min: "<<arr[max_pos]; // cout<<"array is "; // for(int i =0; i<num;i++){ // cout<<arr[i];} }
程序运行实际输出:
enter how many number you want inside :4 Enter a value in array position 0 : 2 Enter a value in array position 1 : 1 Enter a value in array position 2 : 4 Enter a value in array position 3 : 6 max_in 2||min_in1 max_in 4||min_in1 max_in 6||min_in1 max 561||min -1343285512
for循环内部打印的max、min取值符合预期,但循环外部打印的max、min为无意义的随机异常值。
错误原因
核心问题是变量作用域遮蔽:
- 你在main函数开头已经声明了外层作用域的
max、min变量 - 但在写for循环初始化语句时,又用
int i=1, max=arr[0], min=arr[0]重新声明了两个和外层变量同名的局部变量,这两个变量的作用域仅在当前for循环内部生效 - 循环内你赋值、打印的都是for块内的局部
max/min,外层main函数开头声明的max/min从来没有被赋值过,所以循环结束后访问外层变量,读到的是栈上的未初始化随机垃圾值,就是你看到的异常数字。 - 另外你的最值判断逻辑还有额外bug:判断时加了
arr[i]>arr[i-1]/arr[i]<arr[i-1]的相邻比较条件,会漏掉最值出现在非相邻位置的情况,而且max_pos、min_pos也没有初始化首元素位置,首元素为最值时会出现位置错误。
修正方案
- 去掉for循环初始化语句里对
max、min的重复声明,直接给外层已经声明的变量赋值 - 初始化最值时同步给
max_pos、min_pos赋初始值0(对应数组首元素下标) - 去掉最值判断里多余的相邻元素比较条件,只需要把当前元素和当前记录的最值比较即可
- 放开注释掉的交换逻辑,完成最值互换功能
修正后的完整可运行代码:
#include<iostream> using namespace std; int main(){ int num, arr[200],max,min,max_pos,min_pos; cout <<"enter array size: "; cin >> num; for (int i=0; i<num; i++){ cout<<"Enter a value in array position "<<i<<" : "; cin>>arr[i]; } // 初始化最值和对应位置,不要重复声明变量 max = arr[0]; min = arr[0]; max_pos = 0; min_pos = 0; for(int i=1; i<num; i++){ // 去掉多余的相邻元素比较 if(arr[i]>max){ max = arr[i]; max_pos = i; } if(arr[i]<min){ min = arr[i]; min_pos = i; } cout<<"max_in "<<max<<"||"<<"min_in "<<min<<endl; } cout<<"max_out "<<max<<"||"<<"min_out "<<min<<endl; // 交换最值位置 arr[min_pos] = max; arr[max_pos] = min; cout<<"max: "<<arr[min_pos]<<" || min: "<<arr[max_pos]<<endl; cout<<"array after swap: "; for(int i =0; i<num;i++){ cout<<arr[i]<<" "; } return 0; }
C++中同名局部变量会屏蔽外层作用域的同名变量,写循环、条件判断的初始化语句时要额外注意不要重复声明已经在外层定义的变量,避免出现作用域错误。
内容的提问来源于stack exchange,提问作者Mahmoud
相关产品推荐
相关产品推荐

