Странности if i in [set]...

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Странности if i in [set]...

Сообщение leo_bs » 10.03.2010 02:31:48

компилирую программу в Lazarus'е под ubuntu, при помощи fpc...
имеется следующий кусок кода:
Код: Выделить всё
   
procedure ...
var arr: array of integer;
begin
...
  if i in arr then...
...
end;

при компиляции выдаёт ошибку:
Ошибка: Ожидается тип множества
при этом если вместо arr подставить что-то вроде [.., .. , ..] или сослаться на внешний массив элементов - ошибки не возникает...
почему?
leo_bs
новенький
 
Сообщения: 10
Зарегистрирован: 27.01.2010 03:06:48
Откуда: Йошкар-Ола, Респ. Марий Эл

Re: Странности if i in [set]...

Сообщение Sergei I. Gorelkin » 10.03.2010 05:27:49

Тип выражения справа от in должен быть "множество" (set). Аргумент другого типа, в том числе массив, там не допускается.
При использовании записи [.., ..] компилятор может понять ее как множество, если элементы не повторяются и меньше 255.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Странности if i in [set]...

Сообщение Climber » 10.03.2010 10:54:31

Sergei I. Gorelkin имел ввиду это:
Код: Выделить всё
procedure ...
var arr: set of integer;
begin
...
  if i in arr then...
...
end;
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Странности if i in [set]...

Сообщение Sergei I. Gorelkin » 10.03.2010 13:28:42

Это я в виду не имел. Тип integer в качестве базового типа множества невозможен, максимум byte (не больше 255).
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Странности if i in [set]...

Сообщение Climber » 10.03.2010 14:08:59

Я, в свою очередь, хотел акцентировать внимание на том, что array надо заменить на set. Или это не обязательно??? :shock:
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Странности if i in [set]...

Сообщение Sergei I. Gorelkin » 10.03.2010 15:12:58

Обязательно :)
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Странности if i in [set]...

Сообщение leo_bs » 10.03.2010 18:37:37

Любопытно... не обращал раньше на это внимания ) теперь буду умным и просвещённым человеком! Всем спасибо. :)
leo_bs
новенький
 
Сообщения: 10
Зарегистрирован: 27.01.2010 03:06:48
Откуда: Йошкар-Ола, Респ. Марий Эл

Re: Странности if i in [set]...

Сообщение Tsukasa-mixer » 06.04.2010 01:38:21

Подниму тему.
Код: Выделить всё
if (sr.Attr <> faDirectory) and SR.Name in ['*.gif','*.png','*.jpg'] then ... 

за подобное компилер по репе ошибкой дает =/ ....
а я уже привык множества в делфе использовать в условиях =( или мб както подругому а не писать по студенчески
Код: Выделить всё
if (sr.Attr <> faDirectory) and
    ((SR.Name = '*.gif')or(SR.Name = '*.png')or(SR.Name = '*.jpg')) then
Tsukasa-mixer
новенький
 
Сообщения: 12
Зарегистрирован: 06.04.2010 01:27:37
Откуда: г.Киров

Re: Странности if i in [set]...

Сообщение скалогрыз » 06.04.2010 09:12:45

"умный" синтаксис развращает.

делфи теперь есть связка "regexp + set" ?
Код: Выделить всё
function isImageExt(const FileName: String): Boolean;
var
  s: String;
  i : integer;
const
  images : array [0..2] of string = ('.png', '.gif','.jpg');
begin
  s:=AnsiLowerCase(ExtractFileExt(FileName));
  for i:=0 to length(images)-1 do begin
    Result:=(s = images[i]);
    if Result then Exit;
  end;
  Result:=false;
end;
...
if (sr.Attr <> faDirectory) and isImageExt(Sr.Name) then...

Последний раз редактировалось скалогрыз 06.04.2010 13:19:22, всего редактировалось 1 раз.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Странности if i in [set]...

Сообщение Tsukasa-mixer » 06.04.2010 12:58:40

скалогрыз писал(а):"умный" синтаксис развращает.

делфи теперь есть связка "regexp + set" ?
Код: Выделить всё
function isImageExt(const FileName: String): Boolean;
var
  s: String;
  i : integer;
const
  images : array [0..2] of string = ('*.png', '*.gif','*.jpg');
begin
  s:=AnsiLowerCase(ExtractFileExt(FileName));
  for i:=0 to length(images)-1 do begin
    Result:=(s = images[i]);
    if Result then Exit;
  end;
  Result:=false;
end;
...
if (sr.Attr <> faDirectory) and isImageExt(Sr.Name) then...




Подобный вариант я также знаю - просто привел - пример =)
и да в делфе от Embarcadero можно в условиях вфождения во множества проверять не только цифренное, но и какое угодно.
(пару последних лет писал в Делфе 2009 - по студ. программе получил лицензию дак и писал. но увы всегда питал слабость к кросплатформенному программированию и жить дальше на делфе полностью уже не могу, да и модуле под делфю все платные =( а тут что называется с чистого листа, можно попробывать.)
и вышеописанный вариант в другой программе я решал вот так в делфе - с тарой проге одной =)

Код: Выделить всё
TMediaType = (mNull, mp3, ogg, flac, wav, wma, aac, ape, cda, bml);

function TDM.mediaType(Send: string): TMediaType;
begin
  Send := ExtractFileExt(send);
  Send := AnsiLowerCase(Send);
  if Send = '.mp3'  then begin result:=mp3;   exit; end;
  if Send = '.ogg'  then begin result:=ogg;   exit; end;
  if Send = '.flac' then begin result:=flac;  exit; end;
  if Send = '.wav'  then begin result:=wav;   exit; end;
  if Send = '.wma'  then begin result:=wma;   exit; end;
  if Send = '.aac'  then begin result:=aac;   exit; end;
  if Send = '.ape'  then begin result:=ape;   exit; end;
  if Send = '.cda'  then begin result:=cda;   exit; end;

  if Send = '.bml'  then begin result:=bml;   exit; end;
  result:=mNull;
end;

Ибо кейс в делфе иногда странно ведет себя с string значениями тоже по простому пришлось.
тут видимо подобным образом придется.

И еще вопрос - в вышеописанном коде вы проверял Result, он тут не вылетает по достижении Result'а из процедуры ?

Ну а в общем подход ваш использую - спасибо.
Tsukasa-mixer
новенький
 
Сообщения: 12
Зарегистрирован: 06.04.2010 01:27:37
Откуда: г.Киров

Re: Странности if i in [set]...

Сообщение скалогрыз » 06.04.2010 13:18:21

Tsukasa-mixer писал(а):и да в делфе от Embarcadero можно в условиях вфождения во множества проверять не только цифренное, но и какое угодно.

как я понял синтаксис
Код: Выделить всё
filename in ['*.jpg', '*.gif']

не просто проверяет соответсвие строк (filename='*.jpg' or filename=*.gif), а разбирает маску, и смотрит соответствие имени файла маске.
Т.е. скрытого кода за таким сравнением наворочена уйма. и об его эффективности (и правильности) можно судить, только смотря в ассемблерный код.

Настойчиво рекомендую всем использовать синтаксис Delphi 7. Проблем с портированием кода на FPC не возникнет.

Tsukasa-mixer писал(а):И еще вопрос - в вышеописанном коде вы проверял Result, он тут не вылетает по достижении Result'а из процедуры ?

не должен.
внёс поправочку. в расширениях символ * не нужен.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Странности if i in [set]...

Сообщение Tsukasa-mixer » 06.04.2010 14:22:20

внёс поправочку. в расширениях символ * не нужен.

Да я знаю.
не просто проверяет соответсвие строк (filename='*.jpg' or filename=*.gif), а разбирает маску, и смотрит соответствие имени файла маске.

Смотри пример реализации выше, там так реализовано т.к. потом в кейсе смотреть удобнее по форматам.
Т.е. скрытого кода за таким сравнением наворочена уйма. и об его эффективности (и правильности) можно судить, только смотря в ассемблерный код.

От чего и хочу линять с делфи, т.к. модули растут и растут и порой делая тривиальные вещи получаеш не тривиальные размерчики файлов =/ ...
так работая с одним модулем мультимедийный проекте добавление его в uses приводило прыжок размера Exe файла на 10мб =/, а при последующих расширениях возможностей размеры просто ужасали =( ...
вчера скачал лазарь и в принципе пока устраивает - особенно то что никто не норовит всю систему засунуть в один *.dcu файл =)
да и размеры exe файлов уже ближе к истине начинают быть похожи =)
еще бы найти реализацию KOL (зеркальных классов)

А и еще вернусь к filename in ['*.jpg', '*.gif']
я в принципе не говорил что он все проверит меня просто смутило что лазарь отказывается проверять вхождение во множество строковых значений, большего и не нужно. а изменить в принципе можно было вот так.
Код: Выделить всё
if (LowerCase(ExtractFileExt(SR.Name)) in ['.gif','.png','.jpg'] ) then ...

просто досадно что подобная проверка не прокатывает и нужно ухищряться.
Tsukasa-mixer
новенький
 
Сообщения: 12
Зарегистрирован: 06.04.2010 01:27:37
Откуда: г.Киров

Re: Странности if i in [set]...

Сообщение Mr.Smart » 06.04.2010 14:28:19

а почему бы не воспользоваться стандартной функцией?
Код: Выделить всё
uses strutils;
const
  exts:  array[0..2] of String = ('.gif','.png','.jpg');
begin
  if AnsiIndexStr(ExtractFileExt(SR.Name),exts)<>-1 then ...
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Странности if i in [set]...

Сообщение Tsukasa-mixer » 06.04.2010 14:37:20

Mr.Smart писал(а):а почему бы не воспользоваться стандартной функцией?
Код: Выделить всё
uses strutils;
const
  exts:  array[0..2] of String = ('.gif','.png','.jpg');
begin
  if AnsiIndexStr(ExtractFileExt(SR.Name),exts)<>-1 then ...

Код: Выделить всё
AnsiIndexStr()

Не знаком ес чесно с данной функцией. - опробую , спс.!

Работает =) такой вариант уже ближе к истине.но с множествами придется осторожней обращаться )
Tsukasa-mixer
новенький
 
Сообщения: 12
Зарегистрирован: 06.04.2010 01:27:37
Откуда: г.Киров


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 47

Рейтинг@Mail.ru