我正在尝试一个测试,我写了这个程序。。。
#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的语句进行循环,否则它将永远持续下去。