Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.17;
Скачать: CL | DM;

Вниз

Недоумение в вопросе использования оператора 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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.063 c
2-1157012712
Perf2k2
2006-08-31 12:25
2006.09.17
Как лучше подключаться к MySQL через Delphi


2-1157019200
yel
2006-08-31 14:13
2006.09.17
Как послать сообщение?


15-1155883344
Хтота
2006-08-18 10:42
2006.09.17
Кеплер


10-1123407931
ищущий ответ
2005-08-07 13:45
2006.09.17
почему не работает пример


3-1152805342
juice
2006-07-13 19:42
2006.09.17
2 датасета и ApplyUpdates