delphi中case of问题

case a of 这个的a只能是整型数字呀!您可以这样做,用ComboBox1.ItemIndex属性来做:

i:= ComboBox1..ItemIndex;
case i of
0: ADOTable1.FieldByName('pid').AsString:= '0';//对应***部
1: ADOTable1.FieldByName('pid').AsString:= '1';//对应人事部
2: ADOTable1.FieldByName('pid').AsString:= '2';//财务部
3: ADOTable1.FieldByName('pid').AsString:= '3';//技术部
----------------------------------------------
针对您的补充,回答:
问题补充:i:=ComboBox1.ItemIndex; 报错Incompatible, types:'string' and 'Integer'//没有定义i,您必须先定义i:integer;
case i of 报错Ordinal type required
0: ADOTable1.FieldByName('pid').AsString:= 1; 报错Incompatible types:'string' and 'Integer'// 用‘’把1括起来,因为是字符串的。
1: ADOTable1.FieldByName('pid').AsString:= 2; 同上// 用‘’把2括起来,因为是字符串的。
2: ADOTable1.FieldByName('pid').AsString:= 3; 同上// 用‘’把3括起来,因为是字符串的。

 

===================================================================

 

 

 

只用过几天的vb,   不知道vb怎样.


对于in来判断一个字符串是否在集合中,你可以绕一下,不用集合,使用AnsiIndexStr。

比如:
S   :=   'ABC ';
case   AnsiIndexStr(S,   [ 'ABC ',   'DEF ',   'GHI '])   of
    0:   //ABC
    ;
    1:   //DEF
    ;
    2:   //GHI
    ;
end;

in是二进制操作符,相当于test指令,相当于判断(element   and   elements)   >   0。如果允许string
作为集合的元素,那么首先集合会变成一个Variant   array,因为集合的成员已经不能用位来
表示这么简单了,这样的话,你声明一个简单集合,在不支持字符串的情况下可能只需要1个
字节,如果支持string的话,就会大得多,而且集合操作极其低速,因为要对variant   array
进行操作,要判断数组的长度,元素的类型。这当然比不上的位操作来得快,也许你到时候
又要抱怨为什么它的in操作为什么这么慢了,集合要占这么多内存,你甚至也会像这里的一
位大佬那样说,pascal太次了。

对于为什么case只接受有序类型(枚举也是有序类型),不接受其他类型如字符串,大概原因可
能和字符串不能作为集合元素的原因相同。

至于为什么不能使用:
case   Sender   of
    Button1:   stmt1;
    Button2:   stmt2;
    ...
end;
的原因,我想可能是语义问题。

如果不限制判别式为常量表达式,会导致语义二义性,
如果Button1或Button2是变量或函数调用,那么运行时,Button1和Button2有可能等值。那
么当Sender   =   Button1   =   Button2时,到底执行stmt1,   还是执行stmt2呢?

你还是可以绕一下,这样调用:

if   Sender   is   TComponent   then
    case   TComponent(Sender).Tag   of
        1:   //Button1
        ;
        2:   //Button2
        ;
        ...
    end;
当然前提是各个Button的tag是unique的。

除了二义性,还有一个是优化的问题,如果限制使用常量表达式,则代码通常较为有效一点。

像这样的语句:
case   TComponent(Sender).Tag   of
    1:   stmt1;
    3:   stmt3;
    5:   stmt5;
    ...
    n:   stmtn;
else
    stmt_else;
end;

当case分支足够长,编译的大概会像这样编指令序列:
编译器预先计算好这样一个指令偏移表:
jmp_offset[1..n]   =   (
        addr_of_stmt1   -   addr_of_stmt_else,             //for   case   1
        0                                                                 ,             //for   case   2
        addr_of_stmt3   -   addr_of_stmt_else,             //for   case   3
        0                                                                 ,             //for   case   4
        addr_of_stmt5   -   addr_of_stmt_else,             //for   case   5
        ...,
        addr_of_stmtn   -   addr_of_stmt_else               //for   case   n
);   //如果else的机会较小则可能会以addr_of_stmt1来作为基地址

register   :=   TComponent(Sender).Tag;
compare   register,   0
if   less_or_equal   then   goto   stmt_else
compare   register,   n
if   great_than   then   goto   stmt_else
goto   addr_of_stmt_else   +   jmp_offset[register]


但是允许变量判别式的话,
case   Sender   of
    Button1:   stmt1;
    Button3:   stmt3;
    Button5:   stmt5;
    ...
    ButtonN:   stmtN;
else
    stmt_else;
end;

则指令序列类似于:
register   :=   Sender;
compare   register,   button1
if   equal   then   goto   stmt1
compare   register,   button3
if   equal   then   goto   stmt3
compare   register,   button5
if   equal   then   goto   stmt5
...
compare   register,   ButtonN
if   equal   then   goto   stmtN

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值