Другие языки программирования и технологии

Почему Индекс находится вне границ массива ?

Такого просто не может быть, но ошибка есть... Не понимаю

type point=record
x,y:real;
end;

function ostr(a,b,c:point):boolean;
var p1,p2,p3:real;
begin
p1:=(b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y); //a
p2:=(a.x-b.x)*(c.x-b.x)+(a.y-b.y)*(c.y-b.y);//b
p3:=(a.x-c.x)*(b.x-c.x)+(a.y-c.y)*(b.y-c.y);//c

if (p1*p2*p3>0) then
ostr:=true;
end;

function ch2(a:point):boolean;
begin
ch2:=(a.x<0)and(a.y>0);
end;
function per(a,b,c:point):real;
begin
per:=sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))+
sqrt(sqr(b.x-c.x)+sqr(b.y-c.y))+
sqrt(sqr(c.x-a.x)+sqr(c.y-a.y));
end;

var a:array[1..50] of point;
n,t,imn,jmn,kmn:integer;
mn:real;
begin
randomize;
repeat
write('Введите количество точек от 3 до 50 n=');
readln(n);

until n in [3..50];
for var i:=1 to n do
begin
a[i].x:=-10+20*random;
a[i].y:=-10+20*random;
end;
writeln('Полученные точки');
for var i:=1 to n do
begin
write(i:2,'(',a[i].x:5:2,';',a[i].y:5:2,') ');
if i mod 5=0 then writeln;
end;
writeln;
t:=0;
for var i:=1 to n-2 do
if ch2(a[i])then
for var j:=i+1 to n-1 do
if ch2(a[j])then
for var k:=j+1 to n do
if ch2(a[k])then
begin
inc(t);
if (t=1) and (ostr(a[i],a[j],a[k])=true) then
begin
mn:=per(a[i],a[j],a[k]);
imn:=i;
jmn:=j;
kmn:=k;
end
else if (per(a[i],a[j],a[k])<mn) and (ostr(a[i],a[j],a[k])=true) then
begin
mn:=per(a[i],a[j],a[k]);
imn:=i;
jmn:=j;
kmn:=k;
end;
end;
if t=0 then write('Треугольников соответствующих условиям нет')
else
begin
writeln('Остроугольный треугольник, расположенный строго во II четверти');
writeln('и имеющий минимальный периметр образован точками');
write(imn:2,'(',a[imn].x:5:2,';',a[imn].y:5:2,') '); - ошибка ЗДЕСЬ
write(jmn:2,'(',a[jmn].x:5:2,';',a[jmn].y:5:2,') ');
writeln(kmn:2,'(',a[kmn].x:5:2,';',a[kmn].y:5:2,') ');
write('Периметр=',mn:0:2);
end;
end.
Судя по строке вида „for var i:=1 to n do“ — это PascalABC.Net
Но, тогда что за ересь в остальном коде?
Типа:
« if (p1*p2*p3>0) then ostr:=true; »

А за такое в условии
«if (t=1) and (ostr(a[i],a[j],a[k])=true) then»
вообще нужно отлучать от компьютера и предавать анафеме!

И чему у вас равно значение переменных imn, jmn, kmn, если условие не разу не выполнится?
А я вам скажу чему.
Все три значения будут 0.
Массив у вас индексируется с 1, если что?
Андрей Сорока
Андрей Сорока
56 374
Лучший ответ
Есть там проблема, imn в этой строке может быть равен нулю.
Это очень трудно
ну я смотрю ответов много но по существу ноль (прям как ошибка)

чтож поехали, проблема у нас в этой секции
//такс, условие гласит что треугольник должен лежать во второй четверти и быть острым + с минимальным периметром среди всех найденых
//и мы сразу же летим инкрементить количество найденышей как только детектим вторую четверть...
inc(t);
//и только теперь мы смотрим а не острый ли это треугольник, и тут же смотрим а не во второй ли он четверти
//хотя торчим мы под тремя if которые на эту вторую четверть заточены...
if (t = 1) and (ostr(a[i], a[j], a[k]) = true) then
begin ...end
else
//не не острый? или он не во второй четверти? (yes but actualy no)
//ну так ты подожди давай ещё раз проверим, а попутно посмотрим может периметр отрицательный?!
//ведь минимальный периметр не инициализирован и равен 0!
if (per(a[i], a[j], a[k]) < mn) and (ostr(a[i], a[j], a[k]) = true) then
begin ...end;

в итоге вы вообще можете не зайти в условия и индексы останутся нулевыми, что недопустимо

далее оптимизации (рано но полезно) - чуть выше есть такой
//окей заполняем пока все норм
for var i := 1 to n do
begin
a[i].x := -10 + 20 * random;
a[i].y := -10 + 20 * random;
end;
writeln('Полученные точки');
//но вот это зачем?! вы два раза ходите по одному и тому же месту и это n лишних прогонов
for var i := 1 to n do
begin
write(i:2, '(', a[i].x:5:2, ';', a[i].y:5:2, ') ');
if i mod 5 = 0 then writeln;
end;

ещё одна вещь - переменная t - зачем она? её можно заменить на Boolean который будет просто говорить правда или ложь

далее то за что я недолюбливаю Pascal - нельзя присвоить значение внутри условия. т. е. я немогу сделать так
if ((tmp := per(a[i], a[j], a[k])) < mn) then mn := tmp;
хотя это красиво и экономит вызов функции
вместо этого я вынужден писать так
tmp := per(a[i], a[j], a[k])
if (tmp < mn) then mn := tmp;

хотя нужна новая переменная но это быстрее чем считать дважды.

и ещё одна вещь (да да ты не Джеки) - проверка остроты там есть одна странность
if (p1*p2*p3>0) then ostr:=true;
т. е. если правда то вернуть правду? я правильно понял? но зачем все эти трудности если можно просто вернуть результат сравнения
ostr:=(p1*p2*p3>0);

итого это можно исправить до такого

...
function ostr(a, b, c: point): boolean;
...
begin
...

Result := (p1 * p2 * p3 > 0);
end;

...

var
a: array[1..50] of point;
n, imn, jmn, kmn: integer;
mn, tmp: real;
found: Boolean;

begin
found := false;
...
writeln('Полученные точки');
for var i := 1 to n do begin
a[i].x := -10 + 20 * random();
a[i].y := -10 + 20 * random();
write(i:2, '(', a[i].x:5:2, ';', a[i].y:5:2, ') ');
if i mod 5 = 0 then writeln;
end;

writeln;
for ...
if ch2(a[k]) and ostr(a[i], a[j], a[k]) then begin
tmp := per(a[i], a[j], a[k]);
if (mn = 0) or (mn > tmp) then begin
found := true;
mn := tmp; imn := i; jmn := j; kmn := k;
end;
end;
if not found then write('Треугольников соответствующих условиям нет')
else begin
...
end;
end.
И @ М М @ И
И @ М М @ И
5 038
В какой именно функции? В какой строке?
странно, я проблем не вижу... но, скорее всего, ищите в imn, jmn, kmn

Похожие вопросы