C++数组与循环,都跳出循环了,怎么该循环里还在运行哦?

时间:2022-09-03 10:31:25
在看到一道程序练习题中编程遇到的问题。
感觉for循环用break;语句中断循环有些问题啊!

#include<iostream>
using namespace std;
int main(int argc, char *argv[]){
int n;
cin>>n;
int*a=new int[n];
int i=0;
for (;i<n;i++)
{
 cin>>a[i];
 if (a[i]=='m')
 {
  break;
 }
 cout<<"i:"<<i<<endl;//都跳出循环了,怎么这里还有输出哦?
}
for (int j=i;j<n;j++)//这里相当于没有运行。
{
 a[j]=0;
}
for ( i=0;i<n;i++)
{
 cout<<a[i]<<" ";
}
system("pause");
}


//比如输入10个数,1,2,3,4,5 输入m终止循环,结果奇怪的事情发生了,本来break可以跳出循环的,但是cout<<"i:"<<i<<endl;依然在跳出循环后循环输出运行了4次,直到
i=10,而这4次没有执行cin>>a[i]语句。这是为什么?怎么用break;语句只能选择性中断啊?如果用while循环就没这个问题。
有人说这个是由于a[i]=='m'左操作数只能接收整数,而右边是字符,所以需要显示强制类型转换,但是我发现即使用强转也无法解决for循环在中断循环后,i累加到10的问题。

9 个解决方案

#1


cin>>a[i];
如果你输入一个字符,cin读取失败,a[i]还保持原先的值而不是'm',所以不会break的。

#2


VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

#3


提醒:调试前请重建所有。

#4


引用 1 楼  的回复:
cin>>a[i];
如果你输入一个字符,cin读取失败,a[i]还保持原先的值而不是'm',所以不会break的。

那为什么我输入10个数。1,2,3,4,5后输入M后,剩下的4次循环 不执行cin>>a[i];语句,而执行cout<<"i:"<<i<<endl;语句哦。cin读取失败后,cin>>a[i];语句就一直不执行了?那你怎么解释用while语句怎么就没这个问题呢?给你while语句的代码看看。

int n;
cin>>n;
int*a=new int[n];
int i=0;
while (cin>>a[i]&&i<n)//这里替换成while循环怎么就没有你说的问题哦?
{
if (a[i]=='m')
{
break;
}
i++;
}

是不是这个和while和for的内部机制原理有关?

#5


我运行后,发现确实如你所说。
我觉得可能是这样。因为a是整型指针,而你输入字符m时,可能当成了非法字符,导致读取失败。由于没有清楚缓冲区,所以非法字符一直存在,导致接下来一直读取失败。你可以试下fflush类型的语句调试下。
break是可以用在for里的,这里因为一些IO的非常规操作导致看似不合常理。
仅供参考。不过你说在while里可行,值得进一步探讨。

#6


为什么不可以,你输入多少就不能继续执行呢?

#7


Gonefar的是正確答案

std::cout << int('m')<<std::endl;
    int n;
    std::cin>>n;
    int *a=new int[n];
    int i=0;
    for (;i<n;i++)
    {
        std::cin>> a[i];
        if(std::cin)
        {
          if (a[i] == int('m'))
          {
            std::cout<<"break"<<std::endl;
            std::cout << a[i] << std::endl;
            break;
          }
        }
        else if(!std::cin)
        {
            std::cout<<"cin is malfunction"<<std::endl;
            break;
        }
        std::cout<<"i:"<<i<<std::endl;//都跳出循环了,怎么这里还有输出哦?
    }

int不能讀取char的,那會構成未定義的行為

#8


这问题不用去翻什么asm啦,直接看C++ primer(第三版)的第八章比较快

#9


我明白了。多谢各位!

#1


cin>>a[i];
如果你输入一个字符,cin读取失败,a[i]还保持原先的值而不是'm',所以不会break的。

#2


VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

#3


提醒:调试前请重建所有。

#4


引用 1 楼  的回复:
cin>>a[i];
如果你输入一个字符,cin读取失败,a[i]还保持原先的值而不是'm',所以不会break的。

那为什么我输入10个数。1,2,3,4,5后输入M后,剩下的4次循环 不执行cin>>a[i];语句,而执行cout<<"i:"<<i<<endl;语句哦。cin读取失败后,cin>>a[i];语句就一直不执行了?那你怎么解释用while语句怎么就没这个问题呢?给你while语句的代码看看。

int n;
cin>>n;
int*a=new int[n];
int i=0;
while (cin>>a[i]&&i<n)//这里替换成while循环怎么就没有你说的问题哦?
{
if (a[i]=='m')
{
break;
}
i++;
}

是不是这个和while和for的内部机制原理有关?

#5


我运行后,发现确实如你所说。
我觉得可能是这样。因为a是整型指针,而你输入字符m时,可能当成了非法字符,导致读取失败。由于没有清楚缓冲区,所以非法字符一直存在,导致接下来一直读取失败。你可以试下fflush类型的语句调试下。
break是可以用在for里的,这里因为一些IO的非常规操作导致看似不合常理。
仅供参考。不过你说在while里可行,值得进一步探讨。

#6


为什么不可以,你输入多少就不能继续执行呢?

#7


Gonefar的是正確答案

std::cout << int('m')<<std::endl;
    int n;
    std::cin>>n;
    int *a=new int[n];
    int i=0;
    for (;i<n;i++)
    {
        std::cin>> a[i];
        if(std::cin)
        {
          if (a[i] == int('m'))
          {
            std::cout<<"break"<<std::endl;
            std::cout << a[i] << std::endl;
            break;
          }
        }
        else if(!std::cin)
        {
            std::cout<<"cin is malfunction"<<std::endl;
            break;
        }
        std::cout<<"i:"<<i<<std::endl;//都跳出循环了,怎么这里还有输出哦?
    }

int不能讀取char的,那會構成未定義的行為

#8


这问题不用去翻什么asm啦,直接看C++ primer(第三版)的第八章比较快

#9


我明白了。多谢各位!