Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.03.2013, 08:24   #1
Решетова Алена
Форумчанин
 
Регистрация: 13.12.2012
Сообщений: 116
По умолчанию Pascal. Указатель на функцию в процедуре сортировки.

Здравствуйте. Помогите, пожалуйста. Я пишу программу, в которой запись из файла сортируется быстрой сортировкой. Надо чтобы из программы вызов был именно таким SortSpeed(area,@Compare2) (по правилам лабораторной). Подскажите, пожалуйста, как передать указатель на функцию Compare в процедуру ssort, которая находится в процедуре SortSpeed. Или скажите, что у меня не так. Я уже разные варианты пробовала. На самой сортировке, на строчке "repeat while Compare(a[i],center)...." происходит выход за пределы памяти. Почему?
Код:
{$mode objfpc}
uses dateutils,sysutils; //модули вычисления времени
type TCompareFunc=function(p1,p2:pointer):integer; 
type pchelovek=^chelovek; 
  chelovek = record  
    f: string[20];
    n: string[15];
    o: string[20];
    v: integer;
  end;
type TSortedArray=array of pchelovek; 

Var Area:TSortedArray; 
    f: text;
    
function Compare2(p1,p2:pointer):integer; 
begin
if pchelovek(p1)^.f = pchelovek(p2)^.f then result:=0;
if pchelovek(p1)^.f < pchelovek(p2)^.f then result:=-1;
if pchelovek(p1)^.f > pchelovek(p2)^.f then result:=1;
end;

procedure SortSpeed(A:TSortedArray; Compare:TCompareFunc); 
procedure ssort(left,right:integer);
  var i,j:integer; center,sw:pointer;
 begin
 writeln('vxod///');
    if left>=right then exit;
    writeln('vxod///');
    center:=a[(left+right) div 2]; 
    writeln('vxod///');
    i:=left; j:=right;
    writeln('vxod///');
    repeat
     while Compare(a[i],center)=-1 do inc(i);
     while Compare(a[j],center)=1 do dec(j);
     if i<=j then begin
      sw:=a[i]; a[i]:=a[j]; a[j]:=sw;
      dec(j); inc(i); 
     end;
    until i>j;
    writeln('vxod///');
    ssort(left,j);
    ssort(i,right);
  writeln('///vixod');
 end;
//Var dt:tdatetime;
begin
// dt:=now();
 ssort(1,length(A));
// writeln(stderr,millisecondsbetween(now(),dt));
end;

Var h,i,N:integer;
    s,s2: string;
    
Begin
assign(f, 'Zapis4.txt');
reset(f);
readln(f,s);
N:=StrtoInt(s);
//Writeln(N);
setlength(Area,N);

for h:=0 to N-1 do begin new(area[h]); end;
 
for h:=0 to N-1 do begin 
    readln(f,s); //writeln(s); 
    i:=1;
    s2:='';
    while s[i]<>#32 do begin s2:=s2+s[i]; inc(i); end;
    area[h]^.f:=s2;
    s2:='';
    inc(i);
    while s[i]<>#32 do begin s2:=s2+s[i]; inc(i); end;
    area[h]^.n:=s2;
    s2:='';
    inc(i);
    while s[i]<>#32 do begin s2:=s2+s[i]; inc(i); end;
    area[h]^.o:=s2;
    s2:='';
    inc(i);
    while i<=length(s) do begin s2:=s2+s[i]; inc(i); end;
    area[h]^.v:=StrtoInt(s2);   
end;
 close(f);
 
for h:=0 to N-1 do writeln(area[h]^.f,' ',area[h]^.n,' ',area[h]^.o,' ',area[h]^.v);  
   
SortSpeed(area,@Compare2);
Writeln; 

for h:=0 to N-1 do writeln(area[h]^.f,' ',area[h]^.n,' ',area[h]^.o,' ',area[h]^.v); 

for h:=0 to N-1 do begin dispose(area[h]); end; 
End.
Первые 4 входа отображаются, на пятом уже переполнение. Потому что Compare передаем в SortSpeed, а не в ssort? А как правильно сделать?

Последний раз редактировалось Решетова Алена; 18.03.2013 в 08:32.
Решетова Алена вне форума Ответить с цитированием
Старый 18.03.2013, 08:28   #2
Решетова Алена
Форумчанин
 
Регистрация: 13.12.2012
Сообщений: 116
По умолчанию

Все остальное работает, так как эту же программу писала для других сортировок. Только процедура меняется. Потом оформлю процедуры в модуль. Так что над остальным текстом не заморачивайтесь. Только с этим указателем помогите, пожалуйста.
Решетова Алена вне форума Ответить с цитированием
Старый 18.03.2013, 09:11   #3
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

Цитата:
Код:
    ssort(left,j);
    ssort(i,right);
Вот ваша проблема. У Вас бесконечная рекурсия. Поэтому со временем вы занимаете всю память.
Правильно поставленная задача - три четверти решения.
DiemonStar вне форума Ответить с цитированием
Старый 18.03.2013, 09:22   #4
Решетова Алена
Форумчанин
 
Регистрация: 13.12.2012
Сообщений: 116
По умолчанию

(сама так думаю)
Код:
if left<j then ssort(left,j);
if i<right then ssort(i,right);
или
(нашла код в инете)
Код:
if left<j then ssort(left,j);
if left<right then ssort(i,right);
Но все равно, даже при условии, 4 входа и ошибка
Решетова Алена вне форума Ответить с цитированием
Старый 18.03.2013, 10:30   #5
Решетова Алена
Форумчанин
 
Регистрация: 13.12.2012
Сообщений: 116
По умолчанию

Ну, помогите, пожалуйста(
Решетова Алена вне форума Ответить с цитированием
Старый 18.03.2013, 10:47   #6
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

собственно, как я вижу, проблема возникает когда left - j = 1, тогда каждый раз вызывается аналогичная конструкция (т.е. рекурсия уходит в бесконечность). но подробнее нужно смотреть в отладчике.
Правильно поставленная задача - три четверти решения.
DiemonStar вне форума Ответить с цитированием
Старый 18.03.2013, 13:41   #7
GetMax
Форумчанин
 
Регистрация: 21.10.2010
Сообщений: 588
По умолчанию

Меняем это
Код:
 ssort(1,length(A));
На это
Код:
 ssort(0,length(A) - 1);
Все работает
Пользователь не знает, чего он хочет, пока не увидит то, что он получил.
Для благодарностей WMR R145235935681

Последний раз редактировалось GetMax; 18.03.2013 в 13:49.
GetMax вне форума Ответить с цитированием
Старый 19.03.2013, 13:12   #8
Решетова Алена
Форумчанин
 
Регистрация: 13.12.2012
Сообщений: 116
По умолчанию

О! Спасибо ОГРОМНОЕ!!! )))) И правда... границы не верно были указаны) Я сама то бы и не догадалась( Потому что пример писали для обычного массива от 1 до N и писали ssort(1,N); ну я и скопировала, да так и вставила, забыла изменить. А у меня то массив указателей! Как я могла забыть( В предыдущих примерах с другими сортировками от 0 же делала. Запамятовала( Спасибо!
Решетова Алена вне форума Ответить с цитированием
Старый 19.03.2013, 14:39   #9
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Цитата:
Сообщение от Решетова Алена Посмотреть сообщение
Потому что пример писали для обычного массива от 1 до N
И в С и в Паскале обычный массив от 0 до N-1.
В отличие от Фортрана и Бейсика, где обычный массив от 1 до N.
s-andriano вне форума Ответить с цитированием
Старый 19.03.2013, 18:55   #10
Решетова Алена
Форумчанин
 
Регистрация: 13.12.2012
Сообщений: 116
По умолчанию

Вместе с преподавателем на лекции писали:

Код:
{$mode objfpc}
const N=10;
var a:array[1..N] of integer;
    i:integer;

procedure ssort(left,right:integer);
  var center,i,j:integer; sw:integer;
 begin
   ...
    ssort(left,j);
    ssort(i,right);
 end;

begin

 for i:=1 to n do begin 
  readln(a[i]);
 end;

 ssort(1,N);

 for i:=1 to n do begin 
  writeln(a[i]);
 end;

end.
так что одномерный статический массив у нас от 1 до N. А вот динамический, согласна, от 0 до N-1
Решетова Алена вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передать указатель на указатель в функцию erro Общие вопросы C/C++ 3 29.10.2012 17:59
Как передать указатель на функцию в функцию WIN32APIist Общие вопросы C/C++ 1 27.01.2011 10:35
указатель на функцию. kotjara2 Общие вопросы C/C++ 9 11.02.2010 18:45
Указатель на функцию Роман Радер Общие вопросы C/C++ 2 09.11.2009 00:50
ошибка в процедуре сортировки строк массива halfpenny Паскаль, Turbo Pascal, PascalABC.NET 1 17.06.2009 00:36