使用Repeat Until循环时Min/Max值异常的Pascal技术问题
问题:单个Repeat Until循环能否实现随机数组的求和、最小值与最大值计算
我尝试用Repeat Until循环实现随机数组的求和、最小值(Min)与最大值(Max)计算,但结果不正确;改用For循环则运行正常。请问是否可以仅通过单个Repeat Until循环达成同样的效果?
错误的Repeat Until代码(第一段)
const licz_l = 5; var x, suma, min, max: longint; tab: array [1..5] of longint; begin randomize(); suma := 0; x := 0; repeat tab[x] := random(100); suma := suma + tab[x]; write({'wylosowane liczby : ',}tab[x],';'); min := tab[1]; max := tab[1]; if (tab[x] < min) then min := tab[x]; // max:=tab[1]; if (max < tab[x]) then max := tab[x]; x := x + 1; until x = licz_l; writeln(''); writeln('srednia : ', suma / licz_l : 4 : 4); writeln('min : ', min, #9, 'max : ', max); end.
正常运行的For循环代码(第二段)
const licz_l = 5; var x, suma, min, max: longint; tab: array [0..4] of longint; begin randomize(); suma := 0; x := 0; repeat tab[x] := random(100); suma := suma + tab[x]; write({'wylosowane liczby : ',}tab[x],';'); x := x + 1; until x = licz_l; min := tab[0]; max := tab[0]; for x := 0 to licz_l-1 do begin if (tab[x] < min) then min := tab[x]; if (max < tab[x]) then max := tab[x]; end; writeln(''); writeln('srednia : ',suma/licz_l:4:4); writeln('min : ',min,#9,'max : ',max); end.
问题分析
第一段代码出错的核心原因有两个:
- 数组下标越界:数组定义为
[1..5],但循环初始x=0,第一次循环会给tab[0]赋值,超出数组合法下标范围,引发未定义行为。 - Min/Max重置错误:每次循环都把
min和max重置为tab[1],覆盖之前的计算结果,无法累积更新极值。
可以用单个Repeat Until循环实现,修正后的代码
调整下标逻辑,并将Min/Max的初始化移到循环外,仅在第一次循环时赋值,后续循环仅更新极值即可:
const licz_l = 5; var x, suma, min, max: longint; tab: array [1..5] of longint; // 保持原数组下标范围 begin randomize(); suma := 0; x := 1; // 初始化为数组起始下标 repeat tab[x] := random(100); suma := suma + tab[x]; write('wylosowane liczby : ', tab[x], '; '); // 第一次循环时初始化min和max if x = 1 then begin min := tab[x]; max := tab[x]; end else begin // 后续循环仅更新min和max if tab[x] < min then min := tab[x]; if tab[x] > max then max := tab[x]; end; x := x + 1; until x = licz_l + 1; // x从1开始,到6时停止(对应5个元素) writeln(''); writeln('srednia : ', suma / licz_l : 4 : 4); writeln('min : ', min, #9, 'max : ', max); end.
如果习惯用0开始的下标,也可以调整数组为[0..4],逻辑类似:
const licz_l = 5; var x, suma, min, max: longint; tab: array [0..4] of longint; begin randomize(); suma := 0; x := 0; repeat tab[x] := random(100); suma := suma + tab[x]; write('wylosowane liczby : ', tab[x], '; '); if x = 0 then begin min := tab[x]; max := tab[x]; end else begin if tab[x] < min then min := tab[x]; if tab[x] > max then max := tab[x]; end; x := x + 1; until x = licz_l; writeln(''); writeln('srednia : ', suma / licz_l : 4 : 4); writeln('min : ', min, #9, 'max : ', max); end.
说明
修正后的代码通过两点解决了原问题:
- 确保数组下标始终在合法范围内,避免越界;
- 仅在第一次循环时初始化
min和max为当前生成的随机数,后续循环只根据新数值更新极值,实现累积判断。
内容的提问来源于stack exchange,提问作者Tomasz Jeliński
相关产品推荐
相关产品推荐

