Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 22.10.2012, 13:46
sorockinalex sorockinalex вне форума
Начинающий
 
Регистрация: 08.08.2012
Сообщения: 178
Репутация: 10
По умолчанию Неправильное поведение цикла for...to

Имеется массив beforelbl
Длина массива 0.

Код:
showmessage('High(beforelbl)='+inttostr(High(beforelbl)));
 for i := 0 to High(beforelbl) do
begin
  showmessage('for i := 0 to High(beforelbl) do');
end

showmessage до цикла выдаёт значение "-1", а второй showmessage всё равно показывает, то есть несмотря на то, что 0<-1 цикл всё равно выполняется... в чём дело??? Я же не ставил downto -1
Ответить с цитированием
  #2  
Старый 22.10.2012, 13:51
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Код:
for i:=Low(beforelbl) to High(beforelbl) do
__________________
Пишу программы за еду.
__________________

Последний раз редактировалось NumLock, 22.10.2012 в 13:54.
Ответить с цитированием
  #3  
Старый 22.10.2012, 13:52
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от sorockinalex
Имеется массив beforelbl
Длина массива 0.

Код:
showmessage('High(beforelbl)='+inttostr(High(beforelbl)));
 for i := 0 to High(beforelbl) do
begin
  showmessage('for i := 0 to High(beforelbl) do');
end

showmessage до цикла выдаёт значение "-1", а второй showmessage всё равно показывает, то есть несмотря на то, что 0<-1 цикл всё равно выполняется... в чём дело??? Я же не ставил downto -1
У меня тело цикла ни разу не срабатывает.

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  beforelbl: array of Integer;
  i: Integer;
begin
  showmessage('High(beforelbl)=' + inttostr(High(beforelbl)));
  for i := 0 to High(beforelbl) do
  begin
    showmessage('for i := 0 to High(beforelbl) do');
  end
end;
Ответить с цитированием
  #4  
Старый 22.10.2012, 13:52
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,907
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

У меня вот такой код:
Код:
var
  i:Integer;
  beforelbl:array of Integer;
begin
  showmessage('High(beforelbl)='+inttostr(High(beforelbl)));
  for i := 0 to High(beforelbl) do
    begin
      showmessage('for i := 0 to High(beforelbl) do');
    end
end;
выдает только одно сообщение.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.

Последний раз редактировалось Aristarh Dark, 22.10.2012 в 13:56.
Ответить с цитированием
  #5  
Старый 22.10.2012, 14:05
sorockinalex sorockinalex вне форума
Начинающий
 
Регистрация: 08.08.2012
Сообщения: 178
Репутация: 10
По умолчанию

в том-то и дело, что дело странное, у меня два сообщения, переходит в тело цикла...
Ответить с цитированием
  #6  
Старый 22.10.2012, 14:08
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от sorockinalex
в том-то и дело, что дело странное, у меня два сообщения, переходит в тело цикла...
Создай новый проект, положи на него кнопку и в обработчике OnClick этой кнопки вставь код который я приводил выше.
Входит в тело цикла?

p.s. Какая у тебя версия Delphi?
Ответить с цитированием
  #7  
Старый 22.10.2012, 14:09
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

создай пустой проект и добавь кнопку на форму:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    beforelbl: array of Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
//  SetLength(beforelbl, 4);
  ShowMessage(IntToStr(Low(beforelbl)));
  ShowMessage(IntToStr(High(beforelbl)));
  for i:=Low(beforelbl) to High(beforelbl) do ShowMessage('>>'+IntToStr(i));
end;

end.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #8  
Старый 22.10.2012, 14:17
sorockinalex sorockinalex вне форума
Начинающий
 
Регистрация: 08.08.2012
Сообщения: 178
Репутация: 10
По умолчанию

Delphi 7.0 Build 4.453

если просто так - работает, а в моей проге не хочет.. не пойму в чём дело...
массив создаётся уже в этом же цикле, а размер массива ранее... мсожет быть пока значения в массив не попали, то его размер как-то... хз... не знаю что думать даже...
Ответить с цитированием
  #9  
Старый 22.10.2012, 14:21
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от sorockinalex
Delphi 7.0 Build 4.453

если просто так - работает, а в моей проге не хочет.. не пойму в чём дело...
массив создаётся уже в этом же цикле, а размер массива ранее... мсожет быть пока значения в массив не попали, то его размер как-то... хз... не знаю что думать даже...
Значит ошибка у тебя в другом месте.
Как объявлен массив? И как задаётся его размер?
Ответить с цитированием
  #10  
Старый 22.10.2012, 14:45
sorockinalex sorockinalex вне форума
Начинающий
 
Регистрация: 08.08.2012
Сообщения: 178
Репутация: 10
По умолчанию

Код:
unit UChangesMsg;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, jpeg, ComCtrls, UDataModule;

type
  TFChangesMsg = class(TForm)
    YesButton: TButton;
    NoButton: TButton;
    ActionLbl: TLabel;
    ApplyImage: TImage;
    CancelImage: TImage;
    ChangesImage: TImage;
    procedure ShowBox(titles, before, after: string);
    procedure YesButtonClick(Sender: TObject);
    procedure NoButtonClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    //Запрет перемещения формы
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
  end;

function ChangesMsg(titles, before, after:string):BOOL;

var
  FChangesMsg: TFChangesMsg;
  titleslbl, beforelbl, afterlbl: array of TLabel;
  titles_, before_, after_: TStringList;

implementation

{$R *.dfm}

procedure TFChangesMsg.WMNCHitTest(var Message: TWMNCHitTest);
begin
  inherited;
  with Message do
    if Result = HTCAPTION then
      Result := HTCLIENT;
end;

function ChangesMsg(titles, before,after:string):BOOL;
begin
  try
    FChangesMsg.ShowBox(titles, before, after);
  finally
    if FChangesMsg.ActionLbl.Caption = 'Yes' then Result:=True;
    if FChangesMsg.ActionLbl.Caption = 'No' then Result:=False;    
  end;
end;  


{----- Процедура вызова сообщения -----}
procedure TFChangesMsg.ShowBox(titles, before, after: string);
var
  Pos: Integer;
  i, h, maxcount, maxh, fontsize, txtheight, betweenrows: cardinal;
begin
  fontsize:=12;
  betweenrows:=3;

  Application.CreateForm(TFChangesMsg, FChangesMsg);

  with FChangesMsg do
  begin
    YesButton.Show;
    NoButton.Show;
    ApplyImage.Show;
    CancelImage.Show;

    //делаем TStringList массивы значений
    titles_:= TStringList.Create();
    before_:= TStringList.Create();
    after_:= TStringList.Create();
    StrBreakApart(titles, '<BR>', titles_);
    StrBreakApart(before, '<BR>', before_);
    StrBreakApart(after, '<BR>', after_);

    //Устанавливаем размеры массивов
    try SetLength(titleslbl, titles_.Count) except showmessage('Ошибка: не удаётся установить размер массива titles') end;
    try SetLength(beforelbl, before_.Count)  except showmessage('Ошибка: не удаётся установить размер массива before') end;
    try SetLength(afterlbl, after_.Count)  except showmessage('Ошибка: не удаётся установить размер массива after') end;

    if titles<>'' then
    begin
      //создаём видимый первый столбец Label для каждого значения
      for i := 0 to High(titleslbl) do
      begin
        titleslbl[i] := TLabel.Create(FChangesMsg);
        titleslbl[i].Parent := FChangesMsg;
        titleslbl[i].Font.Color := clBlack;
        titleslbl[i].Font.Size:=fontsize;
        txtheight:=titleslbl[i].Height;

        //Если значения before и after отличаются - выделяем красным
        try
          if before_[i]<>after_[i] then titleslbl[i].Font.Color := clRed;
        except end;

        titleslbl[i].Top := 8 + i * (txtheight + betweenrows);
        titleslbl[i].Left := 8;
        titleslbl[i].Caption := titles_[i];
      end;
    end;

    //Увеличиваем окно, чтобы корректно рассчитались размеры canvas
    maxcount:=titles_.Count;
    maxh := 8 + maxcount * (txtheight + betweenrows)+14;
    Height:= maxh + 80;
    Width:=2000;


    if before<>'' then
    begin
      //Увеличиваем окно, чтобы корректно рассчитались размеры canvas
      if before_.Count>maxcount then
      begin
        maxcount:=before_.Count;
        maxh := 8 + maxcount * (txtheight + betweenrows)+14;
        Height:= maxh + 80;
      end;

      //создаём невидимый второй столбец Label для каждого значения
      for i := 0 to High(beforelbl) do
      begin
        beforelbl[i] := TLabel.Create(FChangesMsg);
        beforelbl[i].Parent := FChangesMsg;
        beforelbl[i].Font.Color := clBlack;
        beforelbl[i].Font.Size:=fontsize;

        //Если значения before и after отличаются - выделяем красным
        try
          if before_[i]<>after_[i] then beforelbl[i].Font.Color := clRed;
        except end;

        beforelbl[i].Top := 8 + i * (txtheight + betweenrows);
        beforelbl[i].Left := 8;
        beforelbl[i].Caption := before_[i];
      end;
    end;

    if after<>'' then
    begin
      //Увеличиваем окно, чтобы корректно рассчитались размеры canvas
      if after_.Count>maxcount then
      begin
        maxcount:=after_.Count;
        maxh := 8 + maxcount * (txtheight + betweenrows)+14;
        Height:= maxh + 80;
      end;

      //создаём невидимый третий столбец Label для каждого значения
      for i := 0 to High(afterlbl) do
        begin
        afterlbl[i] := TLabel.Create(Self);
        afterlbl[i].Parent := FChangesMsg;
        afterlbl[i].Font.Color := clBlack;
        afterlbl[i].Font.Size:=fontsize;

        //Если значения before и after отличаются - выделяем красным
        try
          if before_[i]<>after_[i] then afterlbl[i].Font.Color := clRed;
        except end;

        afterlbl[i].Top := 8 + i * (txtheight + betweenrows);
        afterlbl[i].Caption := after_[i];
        afterlbl[i].Visible := false;
      end;
    end;

    //Освобождаем массивы за ненадобностью - теперь всё хранится в массиве TLabel
    titles_.Free();
    before_.Free();
    after_.Free();

    // Присваиваем заголовок
    If (before='') and (after<>'') then Caption := 'Добавить?';
    If (before<>'') and (after<>'') then
    begin
      Caption := 'Изменить?';
      ChangesImage.Visible := True;      
    end;
    If (before<>'') and (after='') then Caption := 'Удалить?';

    // Оптимизация размеров окна сообщения
    ChangesImage.Top := trunc(maxh / 2)-7;
    Pos := ClientHeight - 33;
    YesButton.Top := Pos;
    NoButton.Top := Pos;
    ApplyImage.Top:=Pos;
    CancelImage.Top:=Pos;

    ShowModal;
  end;
end;

procedure TFChangesMsg.FormActivate(Sender: TObject);
var
  width, maxwidth, fullwidth: cardinal;
  i: cardinal;
begin

  //Определяем ширины текста первого столбца
  width := 0;
  maxwidth := 0;
  if High(titleslbl)>-1 then
  begin
    for i := 0 to High(titleslbl) do
    begin
      //определяем ширину текущего текста
      width := titleslbl[i].Canvas.TextWidth(titleslbl[i].Caption);
      //запоминаем максимальную ширину
      if width > maxwidth then  maxwidth := width;
    end;
    fullwidth:=8+maxwidth;
  end;

  if High(beforelbl)>-1 then
  begin
    for i := 0 to High(beforelbl) do
    begin
      beforelbl[i].Left := fullwidth+8;
      beforelbl[i].Visible := true;
      //определяем ширину текущего текста
      width := beforelbl[i].Canvas.TextWidth(beforelbl[i].Caption);
      //запоминаем максимальную ширину
      if width > maxwidth then  maxwidth := width;
    end;
    fullwidth:=fullwidth+8+maxwidth;
  end;

  if High(afterlbl)>-1 then
  begin
    if length(afterlbl)<>0 then
    begin
      width := 0;
      maxwidth := 0;
      for i := 0 to High(afterlbl) do
      begin
        ChangesImage.Left := fullwidth+8;
        afterlbl[i].Left := fullwidth +8+25+ 8;
        afterlbl[i].Visible := true;
        //определяем ширину текущего текста
        width := afterlbl[i].Canvas.TextWidth(afterlbl[i].Caption);
        //запоминаем максимальную ширину
        if width > maxwidth then  maxwidth := width;
      end;
      fullwidth:=fullwidth+8+25+8+maxwidth;
    end;
  end;
  if fullwidth<272 then fullwidth:=272;
  NoButton.Left := fullwidth+8-90;
  CancelImage.Left:=fullwidth+8-120;

  FChangesMsg.Width:=fullwidth+16;
  Position:=poDesktopCenter;  
end;

procedure TFChangesMsg.YesButtonClick(Sender: TObject);
begin
  Close;
  ActionLbl.Caption := 'Yes';
end;

procedure TFChangesMsg.NoButtonClick(Sender: TObject);
begin
  Close;
  ActionLbl.Caption := 'No';
end;

procedure TFChangesMsg.FormShow(Sender: TObject);
begin
  try Self.Icon.LoadFromFile(GetCurrentDir+'\icons\tpm.ico') except showmessage('Не найдена иконка tpm.ico') end;
  try ChangesImage.Picture.LoadFromFile(GetCurrentDir+'\icons\arrrght.ico') except showmessage('Не найдена иконка arrrght.ico') end;
  try ApplyImage.Picture.LoadFromFile(GetCurrentDir+'\icons\apply.ico') except showmessage('Не найдена иконка apply.ico') end;
  try CancelImage.Picture.LoadFromFile(GetCurrentDir+'\icons\close.ico') except showmessage('Не найдена иконка close.ico') end;
end;

end.
Ответить с цитированием
  #11  
Старый 22.10.2012, 15:02
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

А как должно быть правильно?
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #12  
Старый 22.10.2012, 15:16
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Потестировал модуль UChangesMsg - глюков не заметил...
При каких условиях возникает глюк?
Ответить с цитированием
  #13  
Старый 22.10.2012, 15:18
sorockinalex sorockinalex вне форума
Начинающий
 
Регистрация: 08.08.2012
Сообщения: 178
Репутация: 10
По умолчанию

думаю, цикл от 0 до -1 с заданием его в виде:
Код:
for i:=0 to -1 do
не должен выполняться...
надо записывать его так:
Код:
for i:=0 downto -1 do

так и не разобрался где ошибка, или не ошибка. в коде выше обошёл просто дополнительным условием
Ответить с цитированием
  #14  
Старый 22.10.2012, 15:19
sorockinalex sorockinalex вне форума
Начинающий
 
Регистрация: 08.08.2012
Сообщения: 178
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Потестировал модуль UChangesMsg - глюков не заметил...
При каких условиях возникает глюк?
конечно там глюков и не будет, я ведь обход поставил, дополнительное условие на фиклы в form.activate...
Код:
  if High(afterlbl)>-1 then
  begin
Ответить с цитированием
  #15  
Старый 22.10.2012, 15:28
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от sorockinalex
думаю, цикл от 0 до -1 с заданием его в виде:
Код:
for i:=0 to -1 do
не должен выполняться...
Совершенно верно - такой цикл ни разу не выполнится.
Цитата:
Сообщение от sorockinalex
так и не разобрался где ошибка, или не ошибка. в коде выше обошёл просто дополнительным условием
Я нашёл где у тебя ошибка. Вот здесь, в объявлении переменной i:
Код:
var
  width, maxwidth, fullwidth: cardinal;
  i: cardinal;
Объявлена она у тебя как беззнаковая (т.е. всегда неотрицательная), а ты пытаешься выполнить цикл от 0 до -1.
Итого вместо:
Код:
for i:=0 to -1 do
у тебя получается:
Код:
for i:=0 to 4294967295 do
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
sorockinalex (22.10.2012)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:58.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025