为何不是异常?
源码如下:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AppEvnts;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
I,J:integer;
E:Exception;
begin
J := 0;
try
for I := 1000 downto 0 do //<---为何将本行注释就无法显示“被零除”
J := J + J div I; //<---还是被零除啊!
except
on E:EDivByZero do
begin
//raise Exception.Create('被零除!');
ShowMessage('被零除!');
end; // on E:Exception do
// begin
// showmessage('Exception异常!');
// end;
end;
end;end.
源码如下:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AppEvnts;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
I,J:integer;
E:Exception;
begin
J := 0;
try
for I := 1000 downto 0 do //<---为何将本行注释就无法显示“被零除”
J := J + J div I; //<---还是被零除啊!
except
on E:EDivByZero do
begin
//raise Exception.Create('被零除!');
ShowMessage('被零除!');
end; // on E:Exception do
// begin
// showmessage('Exception异常!');
// end;
end;
end;end.
I,J:integer;
E:Exception;
begin
J := 0; for I := 1000 downto 0 do //<---为何将本行注释就无法显示“被零除” try
J := J + J div I; //<---还是被零除啊!
except
on E:EDivByZero do
begin
//raise Exception.Create('被零除!');
ShowMessage('被零除!');
end; // on E:Exception do
// begin
// showmessage('Exception异常!');
// end;
end;
end;
I,J:integer;
E:Exception;
begin
J := 0; for I := 1000 downto 0 do //<---为何将本行注释就无法显示“被零除”
try
J := J + J div I; //<---还是被零除啊!
except
on E:EDivByZero do
begin
//raise Exception.Create('被零除!');
ShowMessage('被零除!');
end; // on E:Exception do
// begin
// showmessage('Exception异常!');
// end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
I,J:integer;
E:Exception;
begin
J := 0;
I := 0;
try
for I := 1000 downto 0 do //<---为何将本行注释就无法显示“被零除”
J := J + J div I; //<---还是被零除啊!
except
on E:EDivByZero do
begin
//raise Exception.Create('被零除!');
ShowMessage('被零除!');
end; // on E:Exception do
// begin
// showmessage('Exception异常!');
// end;
end;
end;
var
I,J:integer;
E:Exception;
begin
J := 0;
for I := 1000 downto 0 do //<-为何将本行注释就无法显示“被零除”
try
J := J + J div I; //<---还是被零除啊!
exception
ShowMessage('被零除!');
end;
end;
注释for以后,不就是
try
J := J + J div I; //<---还是被零除啊!
exception
ShowMessage('被零除!');
end;
不对吧
如下代码显示,try程序块被忘掉了。
var
I,J:integer;
E:Exception;
begin
J := 0;
try
// for I := 1000 downto 0 do //<---为何将本行注释就无法显示“被零除”
J := J + J div I ; //<---还是被零除啊!
except
on E:EDivByZero do
begin
//raise Exception.Create('被零除!');
ShowMessage('被零除!');
end; end;
ShowMessage('show !'); //added by tjlai 2002.11.18,
end;
怎么会?只不过异常未检查出来,所以才显示“show!”罢了。否则,delphi的异常处理机制不就是摆设了!?
但为何,直接计算就不算异常呢?
不过,还是谢谢你!
那么,加上for 行,为何就发现异常了呢?
请注意这时候,编译器会产生“Vaule assigned to 'J' never used”的Hint。
消除这个编译优化有两种方法:
1)在Project|Options的对话框中的Compiler页去掉Optimization这个勾,重新Build程序。
2)在代码中增加冗余代码,不让编译器优化。如:
procedure TForm1.Button1Click(Sender: TObject);
var
I,J:integer;
begin
J := 0;
I := 0;
try
// for I := 1000 downto 0 do //<---为何将本行注释就无法显示“被零除”
J := J + J div I; //<---还是被零除啊!
//ShowMessage(IntToStr(J));
except
on E:EDivByZero do
begin
//raise Exception.Create('被零除!');
ShowMessage('被零除!');
end; // on E:Exception do
// begin
// showmessage('Exception异常!');
// end;
end;
end;
将J:=1也不对
procedure TForm1.Button1Click(Sender: TObject);
var
I,J:integer;
begin
J := 0;
I := 0;
try
// for I := 1000 downto 0 do //<---为何将本行注释就无法显示“被零除”
J := J + J div I; //<---还是被零除啊!
ShowMessage(IntToStr(J));
except
on E:EDivByZero do
begin
//raise Exception.Create('被零除!');
ShowMessage('被零除!');
end; // on E:Exception do
// begin
// showmessage('Exception异常!');
// end;
end;
end;
因为变量j没有被使用,编译器优化掉了
EDivByZero is raised when an application tries to divide an integer by zero. In practice, this error is easy to trap and correct in a try...except block.
没错,将Project|Options的对话框中的Compiler页去掉Optimization这个勾,重新Build程序。即可,不用再showmessage了。
给分。
我想可能是编译器只能判断简单的语句,对于FOR之类的循环语句可能就必须编译了,还有把j声明成外部变量时,i的初始值并不是零。