Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];

Вниз

Недоумение в вопросе использования оператора CASE   Найти похожие ветки 

 
Германн ©   (2006-08-02 01:27) [0]

Ну никак не понимаю почему компиллятор принимает без вопросов конструкцию:
 case SpinEdit1.Value of
   1,3,5..9,13 : ShowMessage("Выбор из множества "1,3,5..9,13"");
   99 : ShowMessage("Выбор числа "99"");
 end;

, но не принимает следущую:
const
 MySet = [1,3,5..9,13];

procedure TForm1.Button1Click(Sender: TObject);
begin
 case SpinEdit1.Value of
   MySet : ShowMessage("Выбор из множества "1,3,5..9,13""); - Ошибка "Incompatible types: "Integer and Set"
   99 : ShowMessage("Выбор числа "99"");
 end;

Сразу скажу - справку я читал и понимаю, что
set не входит в разряд допустимых значений caseList. Но вот почему не входит!? Чем set хуже A subrange having the form First..Last, where First and Last both satisfy the criterion above and First is less than or equal to Last
или A list having the form item1, ..., itemn, where each item satisfies one of the criteria above?
Извиняюсь за дурной вопрос, заданный ночью. :-(


 
Джо ©   (2006-08-02 01:38) [1]

Ну, оператор in (применяемый в set"ах) и = (косвенно применяемый в case) это, все-таки, разные вещи, негоже их объединять в одной конструкции case :)


 
Германн ©   (2006-08-02 01:45) [2]


> Джо ©   (02.08.06 01:38) [1]
>
> Ну, оператор in (применяемый в set"ах) и = (косвенно применяемый
> в case) это, все-таки, разные вещи, негоже их объединять
> в одной конструкции case :)
>

Вот-вот. "косвенно применяемый в case"! А почему негоже? Уж если компиллятор может разобрать в операторе case "неявный" set, что ему мешает разобрать явный? В чём принципиальное различие?


 
umbra ©   (2006-08-02 10:16) [3]

так ведь SpinEdit1.Value должно быть целого типа. На это и ругается.


 
Ketmar ©   (2006-08-02 10:25) [4]

> [2] Германн ©   (02.08.06 01:45)

в том, что никакого "set" в case нет. а есть syntactic sugar для сравнений.
проще говоря -- ну разные куски кода за это отвечают. раз.
Вирт говорил, что в case такое не надо -- это два (Кэтмар уклоняется от кирпичей %-).


 
Плохиш ©   (2006-08-02 13:17) [5]


> Германн ©   (02.08.06 01:27)

Потому что тип set не относиться к "ordinale" типам, о чём в справке и написано.


 
Германн ©   (2006-08-02 16:22) [6]


> Вирт говорил, что в case такое не надо -- это два (Кэтмар
> уклоняется от кирпичей %-).

Да. До Вирта я кирпич не докину к сожалению :-(


 
Anatoly Podgoretsky ©   (2006-08-02 20:31) [7]

Не докинешь, но фразу Incompatible types: "Integer and Set" понять то в состоянии?


 
Германн ©   (2006-08-02 21:19) [8]


> Anatoly Podgoretsky ©   (02.08.06 20:31) [7]

Не, ну я конечно тупой, но не до такой же степени! :-)


 
Anatoly Podgoretsky ©   (2006-08-02 22:46) [9]

Ты что скрипач красного от зеленого не отличаешь.


 
Германн ©   (2006-08-03 00:05) [10]


> Ты что скрипач красного от зеленого не отличаешь.

- Integer можно сравнить на равенство с другим Integer. Это в операторе case можно сделать.
- Integer можно проверить на вхождение в поддиапазон Integer. Это в операторе case можно сделать.
- Integer можно проверить на вхождение в список других Integer. Это в операторе case можно сделать.
- Integer можно проверить на вхождение в множество set. А вот этого в операторе case сделать нельзя! И вот этого я не понимаю! Непонимаю почему в паскале такое реализовано не было.


 
Сергей М. ©   (2006-08-03 09:23) [11]


> Германн


1,3,5..9,13 в операторе case множеством фактически не является, хотя и синтаксически выглядит как множество.
Паскаль-компилятор хранит и оперирует множествами в виде битовых масок, размеры которых не фиксированы и зависят от объявления того или иного мн-ва.
А оператор case требует ц/ч константы, которые должны определять сами значения, а не какие-то там битовые маски.

Следующий код

type

 TSomeInts = 1..13;
 TIntSet = set of TSomeInts;

var
 MySet: TIntSet;

...
 MySet := [1,3,5..9,13];

приведет к записи в переменную MySet размером в 2 байта значения $23EA.


 
Leonid Troyanovsky ©   (2006-08-03 09:49) [12]


> Германн ©   (03.08.06 00:05) [10]

> - Integer можно проверить на вхождение в множество set.
> А вот этого в операторе case сделать нельзя! И вот этого
> я не понимаю!


Не совсем, чтобы integer.

The range of a set type is the power set of a specific ordinal type,
called the base type...
The base type can have no more than 256 possible values,
and their ordinalities must fall between 0 and 255.

И алгоритм проверки в case несколько другой.

Вообще-то, если б ты рассказал, для чего оное потребовалось,
можно было б, наверное, обсуждать более содержательно.

--
Regards, LVT.


 
Чапаев ©   (2006-08-03 11:48) [13]


> Integer можно проверить на вхождение в множество set. А
> вот этого в операторе case сделать нельзя! И вот этого я
> не понимаю! Непонимаю почему в паскале такое реализовано
> не было.

Вспоминается классическая история о том, как некий профессор со сцены в течении двух часов превозносил достоинства PL/1 (который славится неимоверным количеством неиспользуемых возможностей), а затем в конце речи добавил: этот язык мог бы быть ещё лучше, если бы разработчики добавили ещё такие "фишки" (следует список из двух десятков "фишек")...


 
Германн ©   (2006-08-03 13:24) [14]


> Вообще-то, если б ты рассказал, для чего оное потребовалось,
>
> можно было б, наверное, обсуждать более содержательно.

Рассказать можно.
Есть у меня набор целочисленных констант. Константы определены во внешних устройствах, с которыми работает моя программа и означают то или иное состояние устройств и их частей. Эти состояния можно (и нужно) объединить в группы по неким критериям. В каких-то случаях поведение программы зависит от конкретного состояния устройства, а в каких-то от того к какой группе вышеназванное относится.
Объединил константы в группы путем описания групп как Set. И при получении ответа от устройства легко могу проверить к какой группе относится состояние устройства if DeviceState in MySetN1 then. А вот case не могу таким образом оформить. :-( Как раз добавлял в программу функцию, в которой case очень бы хорошо читался. Вот и запостил сей крик души.


 
Германн ©   (2006-08-03 13:40) [15]

2 Сергей М. ©   (03.08.06 09:23) [11]

> Следующий код
...
> приведет к записи в переменную MySet размером в 2 байта
> значения $23EA.


Это понятно. Я ж уже говорил [8]. Ты вот лучше объясни почему Set of 0..7 занимает один байт, а Set of 1..8 занимает два байта? Ведь казалось бы и там и там максимальное количество элементов множества равно 8.


 
Leonid Troyanovsky ©   (2006-08-03 13:46) [16]


> Германн ©   (03.08.06 13:24) [14]

> к какой группе относится состояние устройства if DeviceState
> in MySetN1 then. А вот case не могу таким образом оформить.
>  :-( Как раз добавлял в программу функцию, в которой case
> очень бы хорошо читался. Вот и запостил сей крик души.


Если константы не пересекаются, то этого можно достичь
с помощью одномерного массива, содержащего индекс группы.

Если массив получается некомпактный, то лучше немного
другой подход: массив записей с полями константа и группа,
упорядоченный по первому полю (для двоичного поиска).

Можно, конечно, пользовать и TList(.Sort), но массив даже проще,
бо, все значения и группы, видимо, известны на этапе компиляции.

--
Regards, LVT.


 
Германн ©   (2006-08-03 13:54) [17]


> бо, все значения и группы, видимо, известны на этапе компиляции.

Да конечно. Разумеется они когда-то могут и измениться, но это уже будет UpDate.
За советы спасибо.


 
Сергей М. ©   (2006-08-03 14:18) [18]


> Германн ©   (03.08.06 13:40) [15]


Да хрен его знает ..
Борланду ж в задницу никто не смотрит) ...Что он изволил выдать - и на том "ку")

Действительно, при Set of 1..8 нулевой бит в маске сброшен, но его обязательное наличие в подобных случаях влияет на размер блока памяти, распределенного под множество.

Склоняюсь к тому, что такая схема реализована Борландом из соображений производительности операций, работающих со множеством.

Например, инструкции BSF, BSR, BT, BTC, BTS, BTR оперируют индексацией битов с нуля. Со стороны Борланда крайне неразумно было бы елозить маской вправо/влево лишь для того чтобы обеспечить это условие.


 
Германн ©   (2006-08-03 14:24) [19]


> Склоняюсь к тому, что такая схема реализована Борландом
> из соображений производительности операций, работающих со
> множеством.
>
> Например, инструкции BSF, BSR, BT, BTC, BTS, BTR оперируют
> индексацией битов с нуля. Со стороны Борланда крайне неразумно
> было бы елозить маской вправо/влево лишь для того чтобы
> обеспечить это условие.

Такая организация множеств была и в TP 5. А тогда этих инструкций ещё и не придумали.


 
Сергей М. ©   (2006-08-03 14:29) [20]


> Германн ©   (03.08.06 14:24) [19]
>
>


Потому она там и была, что инструкций этих тогда еще не было.
А с появлением этих инструкций Борланд справедливо озаботился их эффективным использованием на стыке со своими алгоритмами.


 
Суслик ©   (2006-08-04 00:19) [21]

задай вопрос в боландовых новостных группах - там теоретиков много, объяснит что к чему
думаю borland.public.delphi.language.delphi.general подойтет.


 
Германн ©   (2006-08-04 00:28) [22]


> Суслик ©   (04.08.06 00:19) [21]
>
> задай вопрос в боландовых новостных группах - там теоретиков
> много, объяснит что к чему

Я сам в душе (в той, которая Душа, а не том, который Душ) почвовед! То бишь теоретик.
Да ладно, проехали. Не хватало мне ещё и там прослыть флудером :-)


 
Юрий Зотов ©   (2006-08-04 02:49) [23]

> Чапаев ©   (03.08.06 11:48) [13]

> PL/1 (который славится неимоверным количеством неиспользуемых
> возможностей)

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


 
Ketmar ©   (2006-08-04 09:57) [24]

> [23] Юрий Зотов ©   (04.08.06 02:49)

Юра, я Вам уже говорил, что Ыв -- титан? %-) для того, чтобы использовать все, их эе надо знать! у меня лично сил не хватило. особенно после того, как оно попыталось откомпилировать программу типа "IF THEN". (если мне спросонья не изменяет склероз, именно PL/1 рытался угадать, что имел в виду программер?)


 
Ketmar ©   (2006-08-04 09:57) [25]

демоны. "Ыв" -- это "Вы". только проснулся, опечатываюсь...


 
Separator ©   (2006-08-04 10:04) [26]

const
MySet = [1,3,5..9,13];

procedure TForm1.Button1Click(Sender: TObject);
begin
case SpinEdit1.Value of
  MySet : ShowMessage("Выбор из множества "1,3,5..9,13""); - Ошибка "Incompatible types: "Integer and Set"
  99 : ShowMessage("Выбор числа "99"");
end;


Тут понятно, MySet константа, но если сделать возможность в case обрабатывать тип set, то тогда получается что можно будет реализовать и такую структуру:
type
   TMySet = set of 1..255;
var
   MySet: TMySet = [1,3,5..9,13,99];

procedure TForm1.Button1Click(Sender: TObject);
begin

case SpinEdit1.Value of
  MySet : ShowMessage("Выбор из множества "1,3,5..9,13""); - Ошибка "Incompatible types: "Integer and Set"
  99 : ShowMessage("Выбор числа "99"");
end;
end;

Тогда по case что будет выполняться? 1 позиция или вторая?


 
Германн ©   (2006-08-04 12:35) [27]

2 Separator ©   (04.08.06 10:04) [26]

> Тогда по case что будет выполняться? 1 позиция или вторая?


Тогда бы компиллятор как и сейчас в подобных случаях, но без set"а сказал бы Duplicate case label. Он же не дурак всё-таки :-)


 
pasha_golub(msk)   (2006-08-04 13:34) [28]

А мне вот жутко не хватает:

case StrVal of
"VASYA": ....
"KOLYUNYA": ....
else ....
end;


 
Loginov Dmitry ©   (2006-08-04 15:19) [29]

А так бы вообще красота:

var
 MySet: set of (msLeft, msTop, msBottom, msRight)
...
case MySet of
 [msLeft, msTop]: <левый верхний угол>;
 [msLeft, msBottom]: <левый нижный угол>;
 [msLeft]: <левая сторона>;
 .....
end;


Такая штука реально могла бы пригодиться. И тип легко приводится к перечисляемому. Ан-нет!


 
Anatoly Podgoretsky ©   (2006-08-04 20:31) [30]

Вам всем жутко не хватает IF и понимания, что CASE это ограниченная форма IF


 
Германн ©   (2006-08-04 21:14) [31]


> Anatoly Podgoretsky ©   (04.08.06 20:31) [30]
>
> Вам всем жутко не хватает IF и понимания, что CASE это ограниченная
> форма IF
>

Нам всем всегда чего-то не хватает. Зимою - лета, осенью - весны. :-)


 
Германн ©   (2006-08-05 01:47) [32]

2 Leonid Troyanovsky ©   (03.08.06 13:46) [16]
Кстати, Леонид. Спасибо за Ваш пост ещё раз. Конечно тот проект, который неявно подразумевался в [14] я переделывать не буду. Незачем и никто не оплатит сей труд. Но с учётом будущих проектов Вы помогли мне "проснуться" и постараться продумать схожие вопросы заранее. Если всё же моя фирма перейдет от "хреноблевомотины", которую я упоминал в http://delphimaster.net/view/15-1153604106/
к разумным задачам, (а таковые есть, всем известны, но отложены "на будущее"), мне скорее всего придётся отказаться в ряде случаев от множеств. Хотя этот тип - один из моих наиболее любимых!
P.S.
А как не любить множества человеку, который тесно работает с микропроцессорами?



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.6 MB
Время: 0.036 c
15-1156836324
dom2
2006-08-29 11:25
2006.09.17
Кто переведет...


15-1156393558
vlgrig1961
2006-08-24 08:25
2006.09.17
Есть ли отдельно маленький редактор форм Delphi


15-1156521040
saxon
2006-08-25 19:50
2006.09.17
Тест Джоэла


1-1154291770
UnKnownPeople
2006-07-31 00:36
2006.09.17
Подскажите - как в Delphi работать с WEB-камерой?


15-1155653980
TUser
2006-08-15 18:59
2006.09.17
Призывники деградировали





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский