如果x> y,是否使用"for i:= x to y"定义良好的行为?

Art*_*1st -4 delphi for-loop

直观的答案是永远不会输入循环.在我能提出的所有测试中似乎都是这种情况.我仍然很焦虑,并且在进入循环之前总是测试它.

这有必要吗?

J..*_*... 7

不,没有必要.

文件明确指出:

for counter:= initialValue to finalValue do statement

要么:

for counter:= initialValue downto finalValue do statement

...

如果initialValue等于finalValue,则语句只执行一次.如果在for ... to语句中initialValue大于finalValue,或者在for ... downto语句中小于finalValue,则语句永远不会执行.

没有必要焦虑.

如果我们想进一步研究会发生什么,让我们举几个例子.先考虑一下:

program Project1;
{$APPTYPE CONSOLE}
var
  i : integer;
begin
  for i := 2 to 1 do WriteLn(i);
end.
Run Code Online (Sandbox Code Playgroud)

这会产生一个编译器提示:

[dcc32提示] Project1.dpr(6):H2135 FOR或WHILE循环执行零次 - 删除

因此编译器将简单地抛弃一个循环,其中常量不会产生循环迭代.即使关闭了优化,它也会这样做 - 根本不会为循环生成任何代码.

现在让我们更聪明一点:

program Project1;
{$APPTYPE CONSOLE}
var
  i, j, k : integer;
begin
  j := 2;
  k := 1;
  for i := j to k do WriteLn(i);
end.
Run Code Online (Sandbox Code Playgroud)

这实际上编译了循环.输出如下:

Project1.dpr.8: for i := j to k do WriteLn(i);
004060E8 A1A4AB4000       mov eax,[$0040aba4]   {$0040aba4 -> j = 2}
004060ED 8B15A8AB4000     mov edx,[$0040aba8]   {$0040aba8 -> k = 1}
004060F3 2BD0             sub edx,eax           {edx = k - j = -1} 
004060F5 7C2E             jl $00406125          {was k-j < 0? if yes, jmp to end.}
004060F7 42               inc edx               {set up loop}
004060F8 8955EC           mov [ebp-$14],edx
004060FB A3A0AB4000       mov [$0040aba0],eax
00406100 A118784000       mov eax,[$00407818]       {actual looped section}
00406105 8B15A0AB4000     mov edx,[$0040aba0]
0040610B E8E8D6FFFF       call @Write0Long
00406110 E8C3D9FFFF       call @WriteLn
00406115 E8EECCFFFF       call @_IOTest
0040611A FF05A0AB4000     inc dword ptr [$0040aba0] {update loop var}
00406120 FF4DEC           dec dword ptr [ebp-$14]
00406123 75DB             jnz $00406100             {loop ^ if not complete}
Project1.dpr.9: end.
00406125 E88EE1FFFF       call @Halt0
Run Code Online (Sandbox Code Playgroud)

所以,循环的第一件事就是检查它是否需要执行.如果初始值大于最终值(对于for..to循环),则它会完全跳过它.它甚至不会浪费周期来初始化循环计数器.