下标超出了数组中的范围
这里数组的下标超出范围。
int a[10], i; for (i = 1; i <= 10; i++) a[i] = 0; printf("India");
输出是一个infinte循环,printf语句没有执行。 这是用KN King写的:
当我达到10时,程序将0存储到[10]中。 但是[10]并不存在。 所以0在[9]后立即进入记忆。 如果变量i碰巧跟随内存中的[9] – 可能就是这种情况 – 那么我将被重置为O.导致循环重新开始。
有谁能解释一下?
这将形成无限循环的想法是基于关于如何在内存中布置变量的假设。 特别是,它假定因为i
是在a
之后立即定义 a
,所以它也将在a
之后立即分配在内存中。
这肯定不能保证,但同样肯定会发生。 如果是,则写入a[10]
实际上可能会覆盖i
。 因为它将0
写入不存在的a[10]
,所以实际上将0
写入i
。 然后当循环中的条件检查到i <= 10
,这是真的,所以循环继续 - 每次到达10时, 在评估循环条件之前立即用0重写,所以循环重新开始一开始。
就C或C ++标准而言,它只是未定义的行为 - 当代码写入数组末尾时, 任何事情都可能发生。 它可能会做某些人所期望的事情,或者可能会做一些完全不同且不相关的事情,而这似乎根本没有意义。 编译器可以自由地发出在这种情况下几乎可以执行任何操作的代码(例如,它可以将其诊断为错误,并且根本不发出任何代码)。
要了解一致行为可能是什么:早期版本的gcc有代码来检测实现定义行为的特定情况(非常类似于未定义的行为,除了实现必须记录它的作用)。 在这种情况下,记录的行为相当复杂。 编译器将尝试按顺序执行以下每个操作(并在第一个成功的位置停止):
- 运行nethack(一场比赛)
- 跑流氓(另一场比赛)
- 启动emacs,让它执行一个河内模拟塔
- 打印出“你正处于一个曲折的小通道的迷宫中,都是一样的”。
我可能会得到那些有点错误的命令(这是很久以前的事了),但你明白了。 结果与合理的人可能期望的任何事情无关 。