DELPHI for 语句的循环变量的特别处理

今天写一段收集不同币别列表的小程序,其实就是一小段循环程序,没有想到执行结果和预期完全不一样!

下面的程序根本不能得到正确的结果,按照一般理解,for 循环执行后,iCnt应该等于iCurrCount(除非被中断),可实际上iCnt永远不会等于iCurrCount,苦思不得其解,循环执行后iCnt的值是个完全不相干的数字(如-2),彻底晕倒

procedure TForm1.Button1Click(Sender: TObject);
    type CurrType=record
        Name:string;  //货币名称
        Dsd:string;   //是否第三地
    end;
var
    CurrList:array[0..19] of CurrType;   //最多10种货币(普通,第三地)
    iCurrCount:integer;

  //   得到货币和DSD组合的列表
  //
  procedure GetCurrList(CurrName,Dsd:string);
  var iCnt:integer;
  begin
      for iCnt := 0 to iCurrCount- 1 do
      begin
          if (CurrName=CurrList[iCnt].Name) and (Dsd=CurrList[iCnt].Dsd) then  //此组合已经存在,中止查找
              Break;
      end;
      if iCnt=iCurrCount then  //如果相等,说明数组中不存在此组合,添加之
      begin
          iCurrCount:=iCurrCount+1;
          CurrList[iCurrCount-1].Name:=CurrName;
          CurrList[iCurrCount-1].Dsd:=Dsd;
      end;
  end;
begin
    iCurrCount:=0;
    GetCurrList('USD','N');
    GetCurrList('USD','Y');

    GetCurrList('EUR','Y');
    EDIT1.Text:=INTTOSTR(iCurrCount);
end;

 

iCurrCount永远为0,开始以为是DELPHI优化的BUG(关闭编译优化就有正确的结果),最后查帮助才发现:(看红字)

 

A for statement, unlike a repeat or while statement, requires you to specify explicitly the number of iterations you want the loop to go through. The syntax of a for statement is 

for counter := initialValue to finalValue do statement 

or 

for counter := initialValue downto finalValue do statement 

where

  • counter is a local variable (declared in the block containing the for statement) of ordinal type, without any qualifiers.
  • initialValue and finalValue are expressions that are assignment-compatible with counter.
  • statement is a simple or structured statement that does not change the value of counter.

The for statement assigns the value of initialValue to counter, then executes statement repeatedly, incrementing or decrementing counter after each iteration. (The for...to syntax increments counter, while the for...downto syntax decrements it.) When counter returns the same value as finalValue, statement is executed once more and the for statement terminates. In other words, statement is executed once for every value in the range from initialValue to finalValue. If initialValue is equal to finalValue, statement is executed exactly once. If initialValue is greater than finalValue in a for...to statement, or less than finalValue in a for...downto statement, then statement is never executed. After the for statement terminates (provided this was not forced by a Break or an Exit procedure), the value of counter is undefined.

 

如果循环正常中止,循环变量的值是未定义的。

彻底晕倒了,好像著名的<borland delphi开发人员指南>讲for循环时也没有提到这点。

 

for 循环标准的执行流程
1。循环变量设置初值  iCnt:=0
2。计算总的循环次数 iCurrCount-1  (=-1)
3。循环变量与循环次数比较
   4.    循环变量小于循环次数,执行语句
   4.    循环变量=循环次数,退出
5.循环变量+1
6.go to 3

一般编程语言,都可以比较循环变量和循环次数,来判断循环是全部执行还是中途退出。

现在发现,DELPHI优化时,直接用初值和循环次数去比,省略了第一步,而iCnt作为过程变量,没有被初始化,还是栈里面的随机数字。

 

不知道其它语言是否有这个规定?请不吝指教!       (有时想,语言有太多的特点,实在不是什么好事)

posted @ 2010-09-07 21:45  James-yu  阅读(7048)  评论(0编辑  收藏  举报