[Delphi] Простая Функция и Указатели;

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Jakeroid, 12 Dec 2010.

  1. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Задача:
    Написать DLL с функцией поиска минимума и максимума массива.
    Пишу вот такую вот штуку, но не компилится, подскажите где ошибка.

    Code:
    function MinMaxArray(a: array of integer; pMin, pMax: pointer): boolean stdcall;
    var i, nMin, nMax: integer; 
    begin
    nMin:= 1;
     for i:=2 to 20 do if a[nMin] > a[i] then nMin:= i; 
    nMax:= 1;
     for i:=2 to 20 do if a[nMax] < a[i] then nMax:= i;
    pMin^:= a[nMin]; //Тут вылазит ошибка на обе строки:
    pMax^:= a[nMax]; // "Operator not applicable to this operand type"
    end;
     
    #1 Jakeroid, 12 Dec 2010
    Last edited: 12 Dec 2010
  2. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Понял, в заголовке функции:
    Code:
    pMin, pMax: pointer
    мои указатели нетипизированные(о боже, дайте мне С++), а работаю как с указателями на integer:
    Code:
    pMin^:= a[nMin]; 
    pMax^:= a[nMax];
    Написал:
    Code:
    function MinMaxArray(a: array of integer; pMin, pMax: ^integer): boolean; stdcall;
    А компилятор мне выдает:
    [Error] Project1.dpr(19): Identifier expected but '^' found
     
  3. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Предыдущую проблему решил, внизу страницы новая...
     
    #3 Jakeroid, 12 Dec 2010
    Last edited: 12 Dec 2010
  4. HakaR

    HakaR Active Member

    Joined:
    23 Jul 2009
    Messages:
    301
    Likes Received:
    200
    Reputations:
    3

    Мб так? Не уверен, что правильно.
     
  5. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    А почему не используешь PInteger? (указатель на Integer)
     
    2 people like this.
  6. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Честно? Даже не знал что такой есть.

    Вот все заработало, почти...
    Функция либы:
    Code:
    function MinMaxArray(a: array of integer; pMin, pMax: PInteger):boolean; stdcall;
    var
      i, nMin, nMax: integer;
    begin
    try
      nMin:= 1;
      for i:=2 to 20 do
      if a[i] < a[nMin] then nMin:= i;
      nMax:= 1;
      pMin^:= a[nMin];
      for i:=2 to 20 do
      if a[i] > a[nMax] then nMax:= i;
      pMax^:= a[nMax];
      MinMaxArray:= true;
    except
      MinMaxArray:= false;
    end;
    end;
    Кусок кода программы:
    Code:
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    if MinMaxArray(MassA, @MinValue, @MaxValue) = true
    then
      begin
      Memo1.Lines.Add('Successful!!!');
      Memo1.Lines.Add('Minimal=' + intTOstr(MinValue) + ' ' + 'Maximal=' + intTostr(MaxValue));
      end
    else Memo1.Lines.Add('Function ERROR!!!');
    end;
    Минимальное значение находит правильно, а вот максимальное "1243048" постоянно, хотя в массиве не больше числа не больше 200.
    Где я ошибся? Не правильно передал переменные?
     
  7. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    function MinMaxArray(a: array of integer; var pMin integer; var pMax: integer):boolean; stdcall;

    и будет тебе счастье. Напрямую работай с pMin и с pMax как в обычными числами. И они будут связаны с переменными которые были указаны при вызове функйии
     
  8. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Попробовал - Работает НЕ правильно. Так же ерунда, минимальное находит, максимальное - нет.
     
  9. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    значит криво пишешь раз не работает
     
  10. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Я как бы не отрицаю что я нуб в программировании, но ведь алгоритмы простые, по 10 раз уже разобрал. Минимум праивльно находит - максимум постоянно число 1243068, у друга на машине попробовал у него другое - 1636096, а минимум правильно находит.
    Может я где то в другом месте ошибся?
    Вот код всей проги:
    Code:
    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        Button4: TButton;
        procedure Button4Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
      MassA: array[1..20] of integer; //Мой массив
      MinValue, MaxValue: integer; //Переменные для мин и макс
    
    implementation
    
    {$R *.dfm}
    
    function MinMaxArray(a: array of integer; var pMin: integer; var pMax: integer): boolean; stdcall; external 'MMDLL.dll'; //Подгружаю DLL
    
    procedure TForm1.Button4Click(Sender: TObject); //Кнопка выход
    begin
    Close;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject); //Кнопка рандом для случайного заполнения массива
    var
    i: integer;
    s: string;
    begin
    for i:=1 to 20 do
      begin
      MassA[i]:= 1 + random(200);
      s:= 'A[' + intTOstr(i) + ']=' + ' ' + intTOstr(MassA[i]);
      Memo1.Lines.Add(s);
      end;
    end;
    
    procedure TForm1.Button2Click(Sender: TObject); //Кнопка юзающая MMDLL.dll
    begin
    if MinMaxArray(MassA, MinValue, MaxValue) = true
    then
      begin
      Memo1.Lines.Add('Successful!!!');
      Memo1.Lines.Add('Minimal=' + intTOstr(MinValue) + ' ' + 'Maximal=' + intTOstr(MaxValue));
      end
    else Memo1.Lines.Add('Function ERROR!!!');
    end;
    
    end.

    Вот код DLL:

    Code:
    Library MMDLL;
    
    
    
    uses
      SysUtils,
      Classes;
    
    {$R *.res}
    
    function MinMaxArray(a: array of integer;  var pMin: integer; var pMax: integer):boolean; stdcall;
    var
      i, nMin, nMax: integer;
    begin
    try
      nMin:= 1;
      for i:=2 to 20 do
      if a[i] < a[nMin] then nMin:= i;
      pMin:= a[nMin];
      nMax:= 1;
      for i:=2 to 20 do
      if a[i] > a[nMax] then nMax:= i;
      pMax:= a[nMax];
      MinMaxArray:= true;
    except
      MinMaxArray:= false;
    end;
    end;
    
    exports MinMaxArray;
    
    begin
    end.
    
     
    #10 Jakeroid, 12 Dec 2010
    Last edited: 12 Dec 2010
  11. Jakeroid

    Jakeroid Member

    Joined:
    9 May 2009
    Messages:
    198
    Likes Received:
    12
    Reputations:
    1
    Вот я дурак!
    Просто про нумерацию массива забыл...
    Просто в DLL цикл бегает теперь с 0 до 19 :).
    Всем спасибо.

    P.S. А все, потому что я решил не заморачиваясь скопипастить алгоритм поиска с форума(как я щас понимаю форума быдло кодеров)... А вышло хуже :(
     
    #11 Jakeroid, 12 Dec 2010
    Last edited by a moderator: 14 Dec 2010