有的就是分数,想问一个简单的问题!希望有熟悉的高手解决。分数不够可以追加!在线等待!!!

g58521547 2003-10-20 11:19:43
我再一个调用线程的程序中有一个FOR循环。我发现这个FOR循环的的循环变量I从大到小赋值,可是我明明是从0到127,为什么I第一次却是128?原程序见下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure threaddone(sender:tobject);
public
{ Public declarations }
end;
tmythread=class(tthread)
protected
procedure execute;override;
end;
var
Form1: TForm1;


implementation
const
maxsize=127;
var
doneflags: integer=0;
globalarray:array[0..127] of integer;
nextnumber:integer=0;
cs:trtlcriticalsection;


{$R *.dfm}

function getnextnumber:integer;
begin
inc(nextnumber);
result:=nextnumber;
end;
procedure tmythread.execute;
var
i:integer;
begin
onterminate:=form1.threaddone;
entercriticalsection(cs);
//
for i:=0 to maxsize do
begin
globalarray[i]:=getnextnumber; //1..128
sleep(5);
end;

//
leavecriticalsection(cs);
end;
procedure tform1.threaddone(sender:tobject);
var
i:integer;
begin
inc(doneflags);
for i:=0 to maxsize do
begin
// if i=0 then showmessage(inttostr(i));
listbox1.items.Append(inttostr(globalarray[i]));
//为什么i从128开始呢????
end;
if doneflags=2 then
deletecriticalsection(cs);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
initializecriticalsection(cs);
tmythread.Create(false);
tmythread.Create(false);
end;

end.
...全文
30 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
很土 2003-10-21
  • 打赏
  • 举报
回复
Delphi 在编译时使用指令优化, 循环时直接使用计数寄存器操作, 即是逐个减 1, 同时数组的基地址先加上 Sizeof(v) * (Count - 1), 这样保存操作不会有问题. 但有时也会出问题, 这是 Delphi 编译器中存在的 bug.

for i := 0 to 127 do
a[i] := 15;

lea eax, a
add eax, 4 * 127
mov ecx, 128
@loop1:
mov [eax], 15;
dec eax, 4
loop @loop1
大地精灵 2003-10-21
  • 打赏
  • 举报
回复
建议楼主把那两个过程里定义的变量不要都取成i
g58521547 2003-10-21
  • 打赏
  • 举报
回复
hiflower(花) :
我找到了原因,只要把SLEEP(5)去掉就可以了,
但是我不明白,SLEEP这句,是在数组赋值的时候执行的吧?我跟踪调式发现,数组的值在第一个循环结束后是1。。。128,正确的。
为什么在给LISTBOX1添加值时,开始I=128呢,数组范围是0。。127,为什么不报告边界错误呢,
gx 2003-10-21
  • 打赏
  • 举报
回复
同意crossbow(【带三尺剑立不世之功】)
hiflower 2003-10-21
  • 打赏
  • 举报
回复
找到原因,
procedure tform1.threaddone(sender:tobject);
var
i:integer;
begin
inc(doneflags);
entercriticalsection(cs); // 这样才能确保显示 129..256(128 项),
// 否则显示的是两个线程的混合并且是混排的结果(256项),显示结果数据的顺序取决于 CPU 时间,在此例中,线程中每赋一个值,休息 5 毫秒,因此 ListBox 中显示的第一项是线程2 产生的值(因为线程2 早等在那儿了),后面显示线程1产生的 127 个值(5毫秒足够了),再显示线程2 产生的 128 个值。
for i:=0 to maxsize do
begin
listbox1.items.Append(inttostr(globalarray[i]));
end;
leavecriticalsection(cs);
if doneflags=2 then
deletecriticalsection(cs);
end;

至于你看到的 i 值为 128,这可能是 IDE 的 BUG 了,它的真实内容还是 0。
tom20803862 2003-10-21
  • 打赏
  • 举报
回复
// if i=0 then showmessage(inttostr(i));
listbox1.items.Append(inttostr(globalarray[i]));
//为什么i从128开始呢????

我想问题是这儿:globalarray[i]

试试 加一个变量 ii : integer;

然后改程序为

// if i=0 then showmessage(inttostr(i));
ii:=i;
listbox1.items.Append(inttostr(globalarray[ii]));
//为什么i从128开始呢????
hiflower 2003-10-21
  • 打赏
  • 举报
回复
不对不对,这样写没错啊,很奇怪了
hiflower 2003-10-21
  • 打赏
  • 举报
回复
老兄,你写错了!

procedure TForm1.Button1Click(Sender: TObject);
begin
initializecriticalsection(cs);
tmythread.Create(false);
// tmythread.Create(false); // 重复了
end;
g58521547 2003-10-21
  • 打赏
  • 举报
回复
怎么没有人回答我呀,既然没有我要结贴了

谢谢各位帮忙。
lushaox 2003-10-20
  • 打赏
  • 举报
回复
For i:=0 to maxsize-1 do
Bebin
......
end;
试一试
crossbow 2003-10-20
  • 打赏
  • 举报
回复
真是邪们了!你用Watch监视i到底是怎么变换的,应该不可能出这样的问题的...
g58521547 2003-10-20
  • 打赏
  • 举报
回复
还是失败呀!!!
wenliqiang 2003-10-20
  • 打赏
  • 举报
回复
procedure tform1.threaddone新定义一个别的变量替换i行不行啊?
g58521547 2003-10-20
  • 打赏
  • 举报
回复
楼上的两位,你们的方法我都尝试了,结果还不对,显示为:
129
2
3
....
本来应该从1开始的,为什么是129,因为I一开始就成了128。我想不明白。帮帮忙。谢谢!
delphi2004 2003-10-20
  • 打赏
  • 举报
回复
是不是函数getnextnumber已经把它加到最大值了啊,你不用这个函数试试,直接++好了
cnhgj 2003-10-20
  • 打赏
  • 举报
回复
直接
for i:= 0 to 127试试
g58521547 2003-10-20
  • 打赏
  • 举报
回复
好象不成功呀
还有没有别的想法了?
谢谢

5,379

社区成员

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

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