for i:=1 to 10 do //i从10到1的顺序执行;
t[i]:=99; for i:=1 to 10 do
showmessage(inttostr(i)); //i为动1到10的顺序执行请问是怎么回事情???
t[i]:=99; for i:=1 to 10 do
showmessage(inttostr(i)); //i为动1到10的顺序执行请问是怎么回事情???
第二个for语句i是从10到1的变化
你们运行一下就明白了
从10到1: for i:=10 downto 1 do
不可能吧!!!
for i:=10 downto 10 do //i从10到1的顺序执行; 降序
t[i]:=99; for i:=1 to 10 do
showmessage(inttostr(i)); //i为1到10的顺序执行 升序
明白了:
for i:=10 downto 1 do //i从10到1的顺序执行; 降序
t[i]:=99; for i:=1 to 10 do
showmessage(inttostr(i)); //i为1到10的顺序执行 升序
t[i]:=99;
我们看他实际运行是怎样的:
0045227A mov ebx,$0000000a //循环10次,
0045227F lea eax,[ebp-$28] //EAX指向T[1]的首地址
00452282 mov [eax],$00000063//对其中的一个元素传递99;
00452288 add eax,$04//让EAX指向下一个元素地址
0045228B dec ebx//循环次数减1
0045228C jnz -$0c//如果没有到0就跳到0045227F 地址处运行
t[i]:=99;
大家不信可以自己实验一下,看i实际是不是从10到1执行的,不骗你们的!
我运行了一次
for i:=1 to 10 do //i从10到1的顺序执行;
t[i]:=99;结果是I从1到10
你运行的结果10到1是不可能的!!
t[i]:= i;
for i:=1 to 10 do //i从10到1的顺序执行;
t[i]:=99;
改成
for i:=1 to 10 do //i从1到10的顺序执行;
t[i]:=Abs(i);
就是正常次序了,具体DELPHI为什么要这么做,可能是为了提高效率或BUG吧,不过既然不影响程序运行就算了吧
学过汇编的因该了解些,循环通常利用ECX寄存器递减来控制循环,递减循环的效率要高于递增的,所以pascal编译器把上面的循环变为了等效的递减。第二段,则没办法转化,因为它的循环中间变量有输出。你的编译器一定打开了优化,不然不会这样。类似的情况只有在调试中比如单步跟踪的时候发现,比如偶尔会发现程序不是按照你的代码顺序执行的,而是跳到其他地方执行了一下后回来了;
还有就是有些变量调试过程中看到不到数值,或者告知变量无效,这都是优化的结果,调试的时候建议大家关闭了优化开关。
t[i]:=99;
其实跟是否赋值99没有关系,那是我随便写的,我发现它只是与是否有数组有关!!!
borland的编译器一直很牛,能够减少生成的代码的条数,可以简单的表述如下:
for i:=0 to 10 do 一般编译成:mov cx 0
..
add ax 1
sub 10
jc
...而优化后
mov cx 10
jz
即可。可以看出优化后的代码的条数(上面的汇编是一个概要,实际的请参考delphi的具体)那么为什么有些是无法优化的呢?一般认为,循环体内的执行如果与循环的次序相关就不会优化。将整数转化成string是有输出的,与次序是相关的。所以不会优化。
showmessage(inttostr(i)); //i为动1到10的顺序执行你看到的最上层窗口中显示的是 10,点确定,显示 9,。对吧?
因为它 10 个窗口全部显示了,先显示的被后显示的盖住了,所以感觉是从 10 到 1 的。
t[i]:=99;
for i:=1 to 10 do
showmessage(inttostr(i));
a:=i;或者,可以将Project Options ---> Compiler ---> Optimization(优化编译) 选项关闭,执行结果也会正确。