50分循环的问题,不知是什么原因(50分)

  • 主题发起人 主题发起人 Txh2005
  • 开始时间 开始时间
T

Txh2005

Unregistered / Unconfirmed
GUEST, unregistred user!
一个按钮的点击事件
var ii, i, j, k: integer;
sArr: array[0..50] of char;
begin
for i := 1 to strtoint(Edit11.Text) do
begin
// if i > strtoint(Edit11.Text) then break;
for j := strtoint(ComboBox2.Text) to strtoint(ComboBox3.Text) do
begin
// if j > strtoint(ComboBox3.Text) then break;
for k := strtoint(ComboBox4.Text) to strtoint(ComboBox5.Text) do
begin
// if k > strtoint(ComboBox5.Text) then break;
ii := ilovedephibbs(strtoint(Edit6.Text), j, k, sArr);
if ii = 1 then
ListBox1.Items.Add('成功')
else
ListBox1.Items.Add('错误!');
ListBox1.Items.Add('i:' + inttostr(i) + ' j:' + inttostr(j) + ' k:' + inttostr(k));
application.ProcessMessages;
end;
end;
end;
就是上面这个循环,他变成了个死循环,让我搞了一个小时
在这1个小时里我做了如下调试
1,排除了代码别的地方改变i、j、k的值
2,试着在循环末尾加next --无效
3,屏蔽循环里的唯一函数 ilovedephibbs,有效,不死循环了
4,打开ilovedephibbs,把变量等于的值直接换成数字,也有效
呵呵,有点搞晕了,ilovedephibbs是从串口收发数据的
5,从新启动了电脑 ,还是不行,
最后不得不加上强制中断,各位大虾,这是什么原因?
 
你可以跟踪执行调试一下,看看i,j,k的值是否在变,在什么地方出问题
 
ilovedephibbs 是阻塞的吧?
程序一直在等待 ilovedephibbs 返回信息
 
这不是循环的问题,用 for 是不会有死循环的,i、j、k 的值更加不可能被外部修改,编译器根本就不允许这种操作。
问题就是处在 ilovedephibbs 这个函数里面。
 
to intrain
我跟踪过,i,j,k的值是在变化,当k 从 strtoint(ComboBox4.Text)循环到
strtoint(ComboBox5.Text)的时候,明明k的值已经大于ComboBox5.Text了,但他
还在循环,ComboBox4.Text和ComboBox5.Text的值也就是0到2,我故意让他循,
他到几百了还在循环
to xianguo liyinwei
ilovedephibbs是我DLL里的一个函数,程序不是在等待,而且每次返回值都是
正确的,如果这个函数有问题的话,为什么我把
for k := strtoint(ComboBox4.Text) to strtoint(ComboBox5.Text) do
直接换成
for k := 0 to 2 do 就可以
 
for k := strtoint(ComboBox4.Text) to strtoint(ComboBox5.Text) do
直接换成
for k := 0 to 2 do 就可以
?
可以吗?你的ComboBox4.Text是0,ComboBox5.Text是2 吗?
那你 integer 一个C4和C5,
c4 := strtoint(ComboBox4.Text);c5 := ....
for k := c4 to c5 do
看看效果呢
 
for k := strtoint(ComboBox4.Text) to strtoint(ComboBox5.Text) do
循环次数只和ComboBox4.Text、ComboBox5.Text开始的值有关,后面ComboBox4.Text、ComboBox5.Text值再怎么变化都不影响循环次数,所以
if k > strtoint(ComboBox5.Text) then break;还是必须的。或者改用
k:=strtoint(ComboBox4.Text);
while k<=strtoint(ComboBox5.Text) do
begin
......
end;
 
to 来如风
用了你的建议,
c4 := strtoint(ComboBox4.Text);
c5 := strtoint(ComboBox5.Text);
for k := c4 to c5 do
还是一样死循环,但是把c4和c5换成0和2 就可以.请相信,这是真的
我用watch list 看了他们的值,k会无限大下去,c4,c5 不变
to 黑星星
我也试了你的建议,是可以的,但是我就是搞不懂,怎么会这样?
是不是我的Windows or delphi 有问题,for循环被我用成这样子,呵
以前有的时候用它,还必须要next,否则变量不会+1,不知道大家有没有碰到过
 
for k 的循环里你不是已经把k的值输出到listbox里吗?

这个listbox里显示的k值也是无限增大的??

如果是的话或许真的是你delphi或者机子出问题了,换个while看看
 
procedure TForm1.Button1Click(Sender: TObject);
var
K, I, J: Integer;
begin
for K := 1 to StrToInt(Edit5.Text) do
for I := StrToInt(Edit1.Text) to StrToInt(Edit2.Text) do
for J := StrToInt(Edit3.Text) to StrToInt(Edit4.Text) do
begin
Memo1.Lines.Add(Format('K is :%d; I is :%d; J is :%d', [K, I, J]));
end;
end;
我模拟了一下你的代码,不会出现死循环,现在怀疑ilovedephibbs(strtoint(Edit6.Text), j, k, sArr);这句可能对外部产生了影响,是不是你把这段代码贴出来看看。
 
to 来如风 是啊,我是用listbox输出K值,就是无限大,换while是正常的

to zqw0117 你这样模拟肯定是ok的,
而且我自己屏蔽ilovedephibbs后也是正常的,这个函数是另外单独一个DLL中的函数
执行一些向串口发送、接受数据的代码,如果要检查这个函数的话就要看DLL的代码了
而且有一点点长,所以不好贴,估计不是这个函数的问题吧,如果是的话,那怎么我
把循环的变量直接换成数字或者用While循环就正常?
为什么我把ilovedephibbs屏蔽掉也正常呢?呵呵呵

谢谢大家的关注,只是我到现在还想不通.....我个人确实是想不通,所以才到此来
打扰大家一,耽误大家一点点宝贵的时间
 
是不是在ilovedephibbs中,修改了text的值
 
for k := strtoint(ComboBox4.Text) to strtoint(ComboBox5.Text) do
改为:
k := strtoint(ComboBox4.Text);
for k to strtoint(ComboBox5.Text) do
 
呵呵~写错了
 
ii := ilovedephibbs(strtoint(Edit6.Text), j, k, sArr);
这句改成
f := j;
l := k;
ii := ilovedephibbs(strtoint(Edit6.Text), f, l, sArr);
避免因为dll对堆栈的操作(指针操作),覆盖了j和k的值,导致循环判断语句出错,用另外两个临时变量f和l来代替它们,这样最保险,你试试,应该能解决问题。
 
另外你检查下ilovedephibbs(strtoint(Edit6.Text), j, k, sArr)的声明,是不是stdcall的调用规则,如果和dll使用的规则不一样,这段代码看起来正常,但压栈顺序可能正好相反,哈哈,那就不难理解为什么出错了。
 
ComboBox3.Text.ComboBox5.Text会不会动态改变呢
 
ilovedephibbs是不是更改了变量?
 
猜想,
你这个可能死循环。
var ii, i, j, k: integer;
sArr: array[0..50] of char;
begin
for i := 1 to strtoint(Edit11.Text) do
begin//比如党循环进入这里的时候i:=1 to 100,当i=30的时候,改变ComboBox2.Text,ComboBox4.Text的值,不着成死循环,而是不确定循环次数。
for j := strtoint(ComboBox2.Text) to strtoint(ComboBox3.Text) do
begin
for k := strtoint(ComboBox4.Text) to strtoint(ComboBox5.Text) do
begin
ii := ilovedephibbs(strtoint(Edit6.Text), j, k, sArr);
if ii = 1 then
ListBox1.Items.Add('成功')
else
ListBox1.Items.Add('错误!');
ListBox1.Items.Add('i:' + inttostr(i) + ' j:' + inttostr(j) + ' k:' + inttostr(k));
application.ProcessMessages;/////这里的问题。
end;
end;
end;
 
第一次进来只是看热闹,但看到很多回贴的想法都是错的,所以要说两句。

有一点大家要清楚,黑星星第一句的说法是对的,for to 内置隐藏了三个工作变量,即当
前值,始边界和末边界,并且只赋值一次,所以将k、strtoint(ComboBox4.Text) 、
strtoint(ComboBox5.Text)一次赋值给这些工作变量后,进入循环就不再受它们影响了,
for to只会将当前值返回给k,在循环体内k是只读的,这样可以否定ComboBox4.Text、ComboBox5.Text的值改变的影响,

楼主的问题是k值超出了strtoint(ComboBox5.Text),k在循环体内是只读的,只负责返回
当前值,只有三个工作变量被打乱了,才会......???

zqw0117关于压栈的说法值得研究。但跟J K等没有关系,我认为是压坏了隐藏的三个工作
变量,不过好像不会这样的,主程序没有什么不自然的压栈操作,而dll多弹或者少弹了一
个栈,它无法返回,按楼主的说法,它返回了,证明堆栈99%是没错的,1%也会有意外的,因为确实可以将栈的内容搞乱,但又保持正确返回地址的可能。

application.ProcessMessages释放了控制权,在硬件操作涉及延迟、等待等问题的时候,
或者使用了多线程,往往程序就停在application.ProcessMessages,好像死循环一样,也
不一定,但楼主说的k值超出了strtoint(ComboBox5.Text),证明没有这回事。

帮不了什么,继续看热闹了。
 
后退
顶部