魔鬼代码?

bugcool 2003-01-23 09:01:56
procedure UnpackPlate(sourceFile: string; image:p);
var
k,j,i:integer;
height,width :integer;
PTmp:p;
readbyte:byte;
writebyte:byte;
shiftbyte:byte;
sourceStream :TFileStream;
begin
width := 112; //解压后的宽度
height := 20; //解压后的高度
PTmp := image; //临时指针
if not FileExists(sourceFile) then exit;
try
sourceStream := TFileStream.Create(sourceFile,fmOpenRead or fmShareDenyNone);
try
for i := 0 to height-1 do
begin
sourceStream.Position := (height-1-i)*14;
for j := 0 to (width div 8)-1 do
begin
sourceStream.Read(readbyte,1);
shiftbyte := 1;
for k := 0 to 7 do // k 值从8开始??????
begin
if (shiftbyte and readbyte) > 0 then
begin
writebyte := 0;
end
else
begin
writebyte := 215;
end;
PTmp^:= writebyte;
inc(PTmp);
shiftbyte := shiftbyte shl 1; //一位8次就会报“边界溢出”错
end; //end of for k
end; //end of for j
end; // end of for i
finally
sourceStream.Free;
end;
except
exit;
end;
end;

这是一个过程,其中image是一块内存的指针,在过程外面已经分配好了。这段代码
在以前运行都是好的,昨天发现问题了。
首先,K值竟然是从8开始,共循环8次,到1时就退出K循环了。
其二,shiftbyte := shiftbyte shl 1; 这个左移操作在第8次的时候会抛出一个异常:
---------------------------
Debugger Exception Notification
---------------------------
Project demo.exe raised exception class ERangeError with message 'Range check error'.
其三,还有跟绝的,如果我把左移操作该成:
if k < 7 then
begin
shiftbyte := shiftbyte shl 1;
end;
这个时候再跟踪K值,竟然发现他又是从0开始的了。
其四,i,k值都可以在单步调试的时候可以查看它们的值,而查看j值确报告:由于优化,不能查看
其值????,怎么回事?如果我一定要知到j值呢?


以上四个问题,请大家讨论!
我用的2000 server,d7
昨天还重装过d7,在别的机器上测试这段代码也有同样的问题。


...全文
106 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ehom 2003-01-24
  • 打赏
  • 举报
回复
至于无法获得j的值原因好像也很好理解!解决方法有两个,一是先给一变量赋值,再在循环时使用,效果和上面的k类似!二是在循环中使用j,如加条IntToStr(k),这样不影响程序本身!
ehom 2003-01-24
  • 打赏
  • 举报
回复
这种情况下,由于没有调用k的值,所以只要保证循环8次(从8到1)即可,这样可以减少一条指令,所以编译器进行了优化,没有错!
CloneCenter 2003-01-23
  • 打赏
  • 举报
回复
不会是 Delphi 出了问题了吧?编译器的优化?
你在那个 k 的循环中,没有引用 k 的时候,是不是 k 变量本身就是不存在的,而是在 cx(Ecx) 中放了循环的个数,然后就是汇编中的 Loop 指令;而加了引用 k (就是 if k < 7 then ),然后编译器就实在的给 k 分配了一个变量空间,才有了值?
个人猜测,如有雷同,纯属巧合。
CityhunterID 2003-01-23
  • 打赏
  • 举报
回复
up
jackystar 2003-01-23
  • 打赏
  • 举报
回复
都放假了
bugcool 2003-01-23
  • 打赏
  • 举报
回复
100分得问题也没人看么?
waxi 2003-01-23
  • 打赏
  • 举报
回复
up
angelcorps 2003-01-23
  • 打赏
  • 举报
回复
up
yczyk 2003-01-23
  • 打赏
  • 举报
回复
怎么没人呢?害我还先占了一个位子呢!先占位子再说啦,然后再考虑问题!
diruser 2003-01-23
  • 打赏
  • 举报
回复
CloneCenter(复制中心) 的回答有道理
bugcool 2003-01-23
  • 打赏
  • 举报
回复
哈哈,移位解决方法来了
shiftbyte := byte(shiftbyte shl 1);
进行强制类型转换一下就可以了。

怎么都是我自问自答啊。
bugcool 2003-01-23
  • 打赏
  • 举报
回复

楼上的对K的回答我觉得比较对。

至于移位问题,shitbyte经过7次位移后值是128,如果再左移一位就是
256了,这个时候再赋值给shitbyte就会超出它的取值范围了。
有点不明白,字节型的值怎么会移出个256,应该是0的啊。

5,388

社区成员

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

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