Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Object Pascal: кроссплатформенные технологии > Глюк паскаля???


Автор: vicq 8.7.2007, 13:10
Написал прогу. при пошаговом выполнении считает верно. ответ сходится с точным. а по Ctrl-F9 совсем другие результаты выдает. Паскаль или прога? в чем косяк? smile 

Автор: m0ro 8.7.2007, 13:17
код в студию?

Автор: vicq 8.7.2007, 13:22
в коде бардак... и без коментов:

Код

Program KRAI;
Uses CRT;
Type
   mix=Array[1..50,1..50] of Real;
   intmx=Array[1..50] of Integer;
Var k,i,j:Byte;
    A,B,R,h,x,y,m,n,d,d1,ep,e:Real;
    u,u2,u3:mix;
    indx:intmx;

Function Uh(x,y:Real):Real;
Begin
   Uh:=sqr(x)*sqr(y);
End;

Function way(x2,y2,x1,y1:Real):Real;
Begin
   way:=sqrt(sqr(x2-x1)+sqr(y2-y1));
End;

Function d_x(A,B,R,x,y:Real):Real;
Var dx:Real;
Begin
   If (R-B*y*y)/A>=0 Then
     Begin
        dx:=sqrt((R-B*y*y)/A);
        d_x:=way(x,y,dx,y);
     End
   Else
     d_x:=h+1;
End;

Function d_y(A,B,R,x,y:Real):Real;
Var dy:Real;
Begin
   If (R-B*x*x)/A>=0 Then
     Begin
        dy:=sqrt((R-A*x*x)/B);
        d_y:=way(x,y,x,dy);
     End
   Else
     d_y:=h+1;
End;

Procedure min_d(Var m,n:Real; A,B,x,y:Real);
Var min:Real;
Begin
   If d_x(A,B,R,x,y)<h Then
      min:=d_x(A,B,R,x,y);
   If d_y(A,B,R,x,y)<h Then
     If d_y(A,B,R,x,y)<min Then
       Begin
          n:=sqrt((R-A*sqr(x))/B);
          m:=x;
       End
     Else
       Begin
          n:=y;
          m:=sqrt((R-B*y*y)/A);
       End;
End;



Procedure Calc;
Begin
   For i:=k DownTo 1 Do
     Begin
        j:=1;
        Repeat
          Begin
             x:=(j-1)*h;
             y:=(i-1)*h;
             If ((way(x,y,0,0)>=d) and (way(x,y,0,0)<d1)) Then
               If (d_x(A,B,R,x,y)<h) or (d_y(A,B,R,x,y)<h) Then
                 Begin
                    If i>k-sqrt(R)/2 Then
                      Begin
                         min_d(m,n,A,B,x,y);
                         u[i][j]:=Uh(m,n);
                         u[j][i]:=u[i][j];
                      End;
                 End
               Else
                 Begin
                   indx[i]:=j-1;
                   Continue
                 End
             Else
               Begin
                  If ((x=0) and (y<k+1) and (y>0)) Then
                    u[i][j]:=1/4*(u[i+1][j]+u[i-1][j]+2*u[i][j+1]);
                  If ((y=0) and (x<k+1) and (x>0)) Then
                    Begin
                       u[i][j]:=1/4*(2*u[i+1][j]+u[i][j+1]+u[i][j-1]);
                       u[j][i]:=u[i][j];
                    End;
                  If ((x=0) and (y=0)) Then
                    u[i][j]:=1/4*u[i+1][j];
                  If ((x>0) and (y>0)) Then
                    u[i][j]:=1/4*(u[i+1][j]+u[i-1][j]+u[i][j+1]+u[i][j-1]);
               End;
             j:=j+1;
          End;
        Until(indx[i]>0)
     End;
End;




Procedure init;
Begin
   For i:=1 To 50 Do
     For j:=1 To 50 Do
       u[i][j]:=0;
   For i:=1 To 50 Do
       indx[i]:=0;
End;
Begin ClrScr;
   WriteLn('Ax^2+By^2=R^2');
   WriteLn('vvedite A, B, R');
   Read(A); Read(B); ReadLn(R);
   WriteLn('Vvedite shag setki H'); ReadLn(h);
   WriteLn('Vvedite tochnost E'); ReadLn(e);
   init;
   k:=round(sqrt(R)/h)+1;
   i:=0; j:=k;
   d:=sqrt(R)-(sqrt(2*sqr(h))/7);
   d1:=sqrt(R)+2*h-h/30;
   Calc;
   Repeat
     Begin
        ep:=0;
        For i:=k DownTo 1 Do
           Begin
             For j:=1 to indx[i] Do
               Begin
                  x:=(j-1)*h;
                  y:=(i-1)*h;
                  If ((way(x,y,0,0)>=d) and (way(x,y,0,0)<d1)) Then
                    Begin
                       If (d_x(A,B,R,x,y)<=h) or (d_y(A,B,R,x,y)<=h) Then
                         Begin
                            If i>k-sqrt(R)/2 Then
                              Begin
                                 min_d(m,n,A,B,x,y);
                                 u2[i][j]:=Uh(m,n);
                                 u[j][i]:=u2[i][j];
                              End;
                         End;
                    End
                  Else
                    Begin
                       If ((x=0) and (y<k+1) and (y>0)) Then
                         u2[i][j]:=1/4*(u[i+1][j]+u[i-1][j]+2*u[i][j+1]);
                       If ((y=0) and (x<k+1) and (x>0)) Then
                         Begin
                            u2[i][j]:=1/4*(2*u[i+1][j]+u[i][j+1]+u[i][j-1]);
                            u[j][i]:=u2[i][j];
                         End;
                       If ((x=0) and (y=0)) Then
                         u2[i][j]:=1/4*4*u[i+1][j];
                       If ((x>0) and (y>0)) Then
                         u2[i][j]:=1/4*(u[i+1][j]+u[i-1][j]+u[i][j+1]+u[i][j-1]);
                    End;
                  If u2[i][j]-u[i][j]>ep Then
                    ep:=u2[i][j]-u[i][j];
                  u[i][j]:=u2[i][j];
                End;
           End;
     End;
   Until (ep<e);

   For i:=k DownTo 1 Do
     Begin
     WriteLn;
       For j:=1 to indx[i] Do
             Write(' ',u[i][j]:2:2);
     End;
ReadLn;
End.

Автор: vicq 8.7.2007, 13:54
дело не в коде наверное... почему пошагово одно, а целиком - другое????

Автор: volvo877 8.7.2007, 15:04
Можно посмотреть, с какими данными программа ВООБЩЕ работает? У меня на любых - зацикливается...

Добавлено через 3 минуты и 51 секунду
А вообще - очень интересная позиция: задания - нет, комментариев - нет, исходных данных - нет, что ищем - непонятно. Но "не работает", и сразу виноват во всем Паскаль.

Автор: vicq 8.7.2007, 20:59
есть вапще разница между обычным выполнением проги и пошаговым???

Автор: Crot 9.7.2007, 05:19
Программу не запускал, просто просмотрел.
В твоём коде есть потенциальная ошибка. Читай комментарии:

Код
Procedure min_d(Var m,n:Real; A,B,x,y:Real);
Var min:Real; { здесь ты заводишь ЛОКАЛЬНУЮ переменную min }
Begin
   If d_x(A,B,R,x,y)<h Then  { здесь, ЕСЛИ СРАБАТЫВАЕТ условие }
      min:=d_x(A,B,R,x,y);     { то в переменную min что-то записывается }

  { однако заметь, условие может и не сработать, }
  { и тогда в переменной min будет находиться какое-то заранее не известное число }

   If d_y(A,B,R,x,y)<h Then
     If d_y(A,B,R,x,y)<min Then  { а здесь ты переменную min используешь в логич.выражении }
                                                { хотя записано в ней может быть невесть что }
       Begin
          n:=sqrt((R-A*sqr(x))/B);
          m:=x;
       End
     Else
       Begin
          n:=y;
          m:=sqrt((R-B*y*y)/A);
       End;
End;


Надо учитывать, что:
Значения глобальных переменных к моменту начала выполнения программы обнуляются.
Значения же локальных переменных к моменту начала выполнения ПОДПрограммы - не определены.

P.S.: На всякий случай:
Глобальные переменные - те, которые описанны внутри самой программы.
Локальные переменные - те, которые описанны в любой подпрограмме.
Подпрограмма - процедура или функция.


Цитата
есть вапще разница между обычным выполнением проги и пошаговым???

В твоём случае - есть, так как, ещё раз повторюсь, при вызове процедуры min_d, значение переменной min может быть любое, причём различное при каждом вызове.

Добавлено через 6 минут и 58 секунд
Ещё кое-что заметил:

Код
  ...
   If d_y(A,B,R,x,y)<h Then
     If d_y(A,B,R,x,y)<min Then
       Begin
          n:=sqrt((R-A*sqr(x))/B);
          m:=x;
       End
     Else
       Begin
          n:=y;
          m:=sqrt((R-B*y*y)/A);
       End;
  ...


Следует избегать таких конструкций, используя операторные скобки BEGIN..END. Иначе не ясно, к какому условному оператору IF принадлежит ветка ELSE.

Автор: vicq 9.7.2007, 09:11
Спасибо огромное! определил min и заработало. правда там ещё косяк, но это уже в алгоритме вроде бы. я 2 дня не вставая из-за компа исправлял эту прогу, вот и получилась кривая, с минимумом подпрограмм.

Автор: Nite 10.7.2007, 13:58
vicq, второе замечание Крота про if не забудь.
надо делать так
if ... then
  if ... then
  begin
   ...
  end
  else
  begin
   ...
  end
else ;

иначе конструкция
else
begin
 ...
end
будет отнесена к внешнему if !

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)