100送第一个解决此问题的高手(在线等待,立即给分)

fangchangjiang 2002-11-18 06:39:58
为何不是异常?
源码如下:
unit Unit1;

interface

uses
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.
...全文
19 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
chechy 2002-11-18
  • 打赏
  • 举报
回复
你给分的时候,我在做答,所以给不了了。呵呵。
fangchangjiang 2002-11-18
  • 打赏
  • 举报
回复
为何给不了分,报“贴子回复次数大于跟给分次数 ”
bingshi 2002-11-18
  • 打赏
  • 举报
回复
TO:fangchangjiang(长江)
我想可能是编译器只能判断简单的语句,对于FOR之类的循环语句可能就必须编译了,还有把j声明成外部变量时,i的初始值并不是零。
chechy 2002-11-18
  • 打赏
  • 举报
回复
是的,我就是拷贝了这个。如果不去掉优化,那么就得ShowMessage。
fangchangjiang 2002-11-18
  • 打赏
  • 举报
回复
to chechy(为程序而奋斗) :
没错,将Project|Options的对话框中的Compiler页去掉Optimization这个勾,重新Build程序。即可,不用再showmessage了。
给分。
Liujc 2002-11-18
  • 打赏
  • 举报
回复
看看帮助,就明白
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.
tonylk 2002-11-18
  • 打赏
  • 举报
回复
同意: chechy(为程序而奋斗)的!!!
因为变量j没有被使用,编译器优化掉了
chechy 2002-11-18
  • 打赏
  • 举报
回复
代码弄错了,应该这样:
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;
fangchangjiang 2002-11-18
  • 打赏
  • 举报
回复
to ddqqyy(ddqqyy) :
将J:=1也不对
chechy 2002-11-18
  • 打赏
  • 举报
回复
试了终于明白了。这是编译器优化造成的。因为你这段代码中I和J没有任何用处,J虽然付了两次值,但都没有使用,所以编译器优化了。
请注意这时候,编译器会产生“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;
bingshi 2002-11-18
  • 打赏
  • 举报
回复
把J声明为外部变量就会报错
董董 2002-11-18
  • 打赏
  • 举报
回复
可能是代码被编译器优化的原因:

因初始值 J := 0

则 “J div I”结果,正常情况下总是为零,故“J div I”被优化为总是零,而不用去检测I的值,所以不会出现被零除的情况。
fangchangjiang 2002-11-18
  • 打赏
  • 举报
回复
to bingshi(碎石) :
那么,加上for 行,为何就发现异常了呢?
bingshi 2002-11-18
  • 打赏
  • 举报
回复
因为该过程没有向外界输出计算结果,所以编译器并没有编译它。
也就不会有错误产生。
fangchangjiang 2002-11-18
  • 打赏
  • 举报
回复
to tjlai(西部牛) :
怎么会?只不过异常未检查出来,所以才显示“show!”罢了。否则,delphi的异常处理机制不就是摆设了!?
但为何,直接计算就不算异常呢?
不过,还是谢谢你!
tjlai 2002-11-18
  • 打赏
  • 举报
回复
to fangchangjiang: 这是我的猜想,估计是编译器对代码优化的结果。
如下代码显示,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;
fangchangjiang 2002-11-18
  • 打赏
  • 举报
回复
还没人答对啊!??
fangchangjiang 2002-11-18
  • 打赏
  • 举报
回复
to tjlai(西部牛) :
不对吧
tjlai 2002-11-18
  • 打赏
  • 举报
回复
个人意见,如果注释掉for I := 1000 downto 0 do ,编译器认为,没有变量被引用,当一个程序块内的所有变量都没有被引用时,编译器不会编译那块。所以不会编译try那块,也就不会出现'被零除!'。
fangchangjiang 2002-11-18
  • 打赏
  • 举报
回复
to dyf2001():
注释for以后,不就是
try
J := J + J div I; //<---还是被零除啊!
exception
ShowMessage('被零除!');
end;
加载更多回复(8)

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧