为什么无限循环终止?或者无限



我正在尝试一个测试,我写了这个程序。。。

#include<iostream>
using namespace std;
main()
{
int arr[5]={1,2,3,5,3}, num=5;
for(int i=0; i< num; i++)
{
for(int j=(i+1); i< num; j++)
{
if (arr[i]==arr[j])
{
cout<<"test";
}
cout<<j<<endl;
}
}
}

嗯。。。在下面的代码中,我知道我使用了";i〃;而不是";j";,所以为了制造问题,我使用了这个

for(int j=(i+1); i< num; j++)

我的程序中有问题的部分是

for(int j=(i+1); i< num; j++)
{
if (arr[i]==arr[j])
{
cout<<"test";
}
cout<<j<<endl;
}

在上面的代码中,当我删除这个if块-

if (arr[i]==arr[j])
{
cout<<"test";
}

程序无限。。。。。。。。。但当我再次放入这个if块时,程序在执行一段时间后自动终止。我也在这个链接上读到了这方面的内容,但它显示了java的示例

在那里他们展示了负值的原因,但在我的程序中没有垃圾值。

循环条件从不为false。因此,程序将无限期地继续运行。

但是,对于if (arr[i]==arr[j]),您的访问超出了arr的范围。因此,程序的行为是未定义的。当程序的行为未定义时,它的行为不一定如您所期望的那样。例如,它可能不会无限期地继续运行。

即使没有if (arr[i]==arr[j]),当循环计数器溢出时,循环最终也会有未定义的行为。但是,一个具有未定义行为的程序不一定会像你预期的那样运行。例如,它可能会无限期地继续运行。

如果没有if (arr[i]==arr[j]),您只需要一个无限循环,在这种情况下这是完全有效的。j将继续递增(最终会溢出,在未定义的行为中,请参见[basic.fundamental]/2(,并且该条件永远不会满足,因为i不会改变。

但是,代码中有了if (arr[i]==arr[j])j就会递增,并且您将超出数组的边界(正如您所知(。在C++中,这是未定义的行为,意味着任何都可能发生。在您的情况下,它似乎导致程序崩溃(这实际上是一件好事,因为它表明了一个错误(。

我认为,代码中有问题的部分是

for(int j=(i+1); i< num; j++)

您正在增加j,同时检查i< num

如果你把它换成

for(int j=(i+1); j < num; j++)

它可能会开始工作。

为什么它使用if块终止,而不在没有if块的情况下终止

if (arr[i]==arr[j])
{
cout<<"test";
}

因为CCD_ 12具有有限数量的可能值。当达到int变量的最大值时,value + 1是可能的最小int。(正如@user17732522所指出的,行为可能完全不同——程序崩溃或这里发生了一些令人讨厌的事情——因为int"溢出"的行为是未定义的。因此,你的程序内存可能已经在这里损坏了,它需要执行一些操作才能看到它发生了……例如程序崩溃。(

现在,让我们思考一下arr[i]的作用。arr基本上是指向内存的指针,数组从这里开始,[i]的操作与*(arr + i)相同。

现在,有两种可能

  • i为正并且在数组之外时,程序崩溃
  • i为负时程序崩溃

在这两种情况下,程序都会崩溃,因为您试图访问受保护或不存在的内存区域。这取决于系统的体系结构——例如,在64位AMD64系统的负区中,如果没有16 EB的RAM,那么您显然正在访问不存在的内存。在这种情况下,程序必须导致处理器中断,这会导致操作系统中断,从而导致应用程序死亡。

为什么删除块时它不会崩溃?没有人试图访问*(arr+j(,因此,j从最小可能值到最大可能值重复,没有任何问题。

问题是如果语句始终为真:

for(int j=(i+1); i< num; j++){infinity}

尝试将其设置为:

for(int j=(i+1); j< num; j++){not infinity}

你不能对一个最终不会返回false的语句进行循环,否则它将永远持续下去。

最新更新