答应过要发几篇心得的,第二篇:在 case 语句中使用字符串 (50分)

B

beta

Unregistered / Unconfirmed
GUEST, unregistred user!
// GetEnumValue()就不用作字符串比较了吗?
当然要,而且效率不高,但是我一再强调的是程序的清晰性和可读性。
用汇编效率就高,你什么时候都用它吗?:)
// 《程序员》有类似的文章
我知道,它是用的我的方法的另一种实现(我在回帖中也说过),所以我在方法一后面部分
才一笔代过,以免惹上抄袭之嫌:)
 
S

SS2000

Unregistered / Unconfirmed
GUEST, unregistred user!
// uses TypInfo;
// 记得引用这个单元
// type TMyStrSel = (Beijing, Tianjing, Shanghai, Chongqing);
// 注意,上面这个定义不能放在某个函数内部哦,那样的话,它就没有运行类信息了
// var strSel: TMyStrSel;
str := 'Chongqing';
strSel := TMyStrSel(GetEnumValue(TypeInfo(TMyStrSel), str));
上面语句是使case字符串能成立的关键
如果认为上面的语句简单明了,以上面的代价换取case语句的好处,那就这么做
如果认为上面的语句的代价换取case语句的好处不值得,那就别这么做
我看也没有什么值得争的了,beta无非时发表他的心得,不同意就别这么用,
有什么更好的就说出来。我们也没必要说beta的不好,beta你也别说你的好
大家角度不同,认识就不一样,你说你的效率高,别人说你的效率低,你说你的
可读性强,可别人说你的代码难以理解,呵呵,和为贵
 
B

beta

Unregistered / Unconfirmed
GUEST, unregistred user!
呵呵,前面我说得严重了点,道歉先。
不过说实话,我们这一争论,导致我把这个问题分析得更加透彻,理解更加全面
我认为的确是达到了 讨论 的目的的(虽说气愤可能稍显沉重)
所以我喜欢这样的讨论:)
 
P

Pearl.

Unregistered / Unconfirmed
GUEST, unregistred user!
>>还是因为听了支持您的 Pearl 的由于错误理解效率问题而得出的错误论断,而受了一定的影响呢?
我对效率的理解是错误的吗? 我们毕竟是在写程序,而不是写散文。
我绝不会为了源代码看上去优美而采用更低效的方法。
而且有时我会写一大段代码代替只有几行代码的过程。
也许你会说得不偿失, 但这是我的习惯--为提高运行效率而不择手段。
比如我就永远不会写类似下面这样的代码:
while pos(s1, substring(s, i, l)) > 0do
begin
.... // 改变i的值
end;

再说说case吧, 一般在少于10-15项字符串判断时, 我都用if .. then
.. else
解决的。
在多于这个数时我也不会写if ... then
... else
的(太麻烦), 而是放入一个stringlist里(当然是排序了的, 可以用二分法快速查找)。
但和上面用case语句继续执行的方法不同, 我是直接将各个函数的入口地址放入stringlist.objects中。
找到字符串后就可以直接调用相应的过程了, 这样实现的话一般是两句call指令, 第一句call的是一个无参数(或统一参数)的过程(入口在stringlist.objects中)。 另一句是由这个无参数过程调用的真正解决问题的代码的函数/过程(和无参数过程同名, overload的有参数的过程)。
 

Unregistered / Unconfirmed
GUEST, unregistred user!
我觉得一味去追求程序运行效率而牺牲了程序可读性,这个方法并不可取
 

叮叮当当

Unregistered / Unconfirmed
GUEST, unregistred user!
我一直这样用:
case AnsiIndexStr(City, ['上海', '北京', '重庆', '武汉']) of
0: {上海}
;
1: {北京}
;
2: {重庆}
;
3: {武汉}
;
end;

 
P

Pearl.

Unregistered / Unconfirmed
GUEST, unregistred user!
并不牺牲程序可读性呀。 你完全可以把函数名字取得有意义。
比如:
定义:
type
TProc = Procedure;
TLookupdata=record
s: string;
Proc: TProc;
end;

procedure Beijing;
overload;
procedure Beijing(x: Integer);
overload;
procedure Chengdu;
overload;
procedure Chengdu(s: string);
overload;
....
var
datas: array [0..50] of TLookupData;
初始化:
datas[0].s := 'Beijing';
datas[0].proc := @Beijing;
datas[1].s := 'Chengdu';
datas[1].proc := @Chengdu;
....
实现:
var
b, e, c, n: Integer;
begin
b := 0;
e := high(datas);
while b <= edo
begin
c := (b + e) shr 1;
n := ansicomparestr(Str, datas[c].s;
if n>0 then
e := c-1
else
if n<0 then
b := c+1
else
begin
datas[c].proc;
break;
end;
end;
end;

procedure Beijing;
begin
Beijing(1);
end;

procedure Beijing(a: Integer);
begin
showmessage(inttostr(a));
end;

procedure Chengdu;
begin
chengdu('This is a Test');
end;

procedure Chengdu(s: string);
begin
showmessage(s);
end;

.....
哪点可读性差啦?
 
C

chillkwanjane

Unregistered / Unconfirmed
GUEST, unregistred user!
既然不是讨论效率的话,反正问题也不太重要,那边自己便吧,
反正不要写几十个else
就行了
至于为case而case,为可读性而可读性,...
只要你愿意
 
S

SS2000

Unregistered / Unconfirmed
GUEST, unregistred user!
我觉得大家的讨论有点偏了
如果一段程序的执行时间很长,需要优化,那他的瓶颈
有多少可能是if..then
..else
和case语句造成的?
如果程序运行需要10秒钟,你把if..thne..else
换成
case,或者把case换成if..thne..else
节约几十毫秒
有什么意义?,而且各位的测试不知是如何测试的?
如果一个case语句需要几十毫秒,或者一个10来行
的if..then
..else
需要几十毫秒,那不知各位用的
是什么机器?是386还是286,或者更差是8086,即使
是那些机器,大概也用不了那么多的时间。顺便说一
句,如果用Now函数来计算运行时间,如果运行时间
是秒以上的,还是可用的,如果运行时间是毫秒级的
用这个函数得出的结果是不可靠的,就像100米跑,用
秒表可以分辨两个人的速度,可是如果这一百米是
飞机飞过,一个是800公里/小时,一个是900公里/小时
你的秒表能分得出来吗?
所以通常case或if..then
..else
本身并不是效率的优化对象,
我编程序还基本没有遇到需要优化case或if..then
..else

身的时候,因为case或if..then
..else
本身永远不会成为
瓶颈,因为我们编的是应用程序,除非你的程序就是要处理
case或if..then
..else
本身这种情况,呵呵
 
H

hiler

Unregistered / Unconfirmed
GUEST, unregistred user!
在这里,晚辈有礼了。谢谢大家!
我很想以你们为师。
 
P

Pearl.

Unregistered / Unconfirmed
GUEST, unregistred user!
一个很不恰当的例子:
case是飞机, if...else
是汽车,两种交通工具都能到达你家。
现在你在汽车站, 换5辆车能到家。
你会换5辆车到飞机场然后坐飞机到家吗?
现在讨论的焦点就是要不要这么做呀。
 
W

wxkabc

Unregistered / Unconfirmed
GUEST, unregistred user!
大家在此是为了共同进步,多谈些是好的。
 
I

iwalk

Unregistered / Unconfirmed
GUEST, unregistred user!
知道个屁!知道为什么不说?
像Beta大侠这样愿意发表高论的大富翁还有几个?
Another_Eyes,王寒松,PiPi.等等大侠,今日只存在于离线包了,
大富翁太需要英雄人物了。
对不起我太激动了,我的意思是说:
在Delphi方面我们都没资格“发明”什么,我们至多也就是“发现”一些什么。
要是像在座某些人说的那样,我们不要讨论了,Delphi里面都已经有了!!!。
 

风之彼端

Unregistered / Unconfirmed
GUEST, unregistred user!
T

Traveller

Unregistered / Unconfirmed
GUEST, unregistred user!
我也一直用类似“叮叮当当”的方法,不过以前不知道有AnsiIndexStr这个函数(汗~~~),一直自己实现的。不过感觉可读性最好的就是这种了。
 
B

beta

Unregistered / Unconfirmed
GUEST, unregistred user!
呵呵,那我就再说一遍吧,本文仅仅是提供一种方案,并没有强迫大家使用这种方案。
至于是否清晰,各人有各人的理解,我认为清晰,我可能会用;他认为不清晰他就不这
样用。这很正常,我并没有逼大家都这样用,也不想让大家以为我在这样做。
至于前面和几位富翁的争执,仅仅是为了说服他们个人而已,如果他们不接受,这也是
很平常的事情。就好像我经常劝我的一个朋友学 Delphi,但是他就是要学 CB,但是这
并不影响什么,我们仍然是好朋友。
Pearl:我知道我们现在相互都想说服对方,但是我恐怕您的理由(关于程序清晰程度)
无法说服我;我也知道我无法说服您。就此打住吧,您就当多看到一种无用的方法罢了。
就您这个例子而言,讨论绕弯是否值得,我想我在前面关于清晰性的论述中已经说过了,
不管您是否认同这样的“清晰性”。
开个玩笑,要是坐飞机不要钱的话,我会……[:D]
(没坐过呢)
 
A

Another_eYes

Unregistered / Unconfirmed
GUEST, unregistred user!
iwalk:
我还不仅仅存在于离线包......
 

叮叮当当

Unregistered / Unconfirmed
GUEST, unregistred user!
前面一时疏忽写错了,AnsiIndexStr返回的是以0为基数的序号,已经纠正了。
通常情况下,可读性确是比代码的速度更可贵。
 
J

juanZ

Unregistered / Unconfirmed
GUEST, unregistred user!
不同的方法可以开阔人的思路,我认为主要还是个人喜好和可读性。
毕竟速度在现在的机器上不是最重要的。
 
A

Another_eYes

Unregistered / Unconfirmed
GUEST, unregistred user!
这里高手真多, 看源程序从来不看注解的, 都是看代码就明白了。
都开始讨论可读性是通过代码实现的而不关注解的事了。
看来我真的落伍了。 汗颜哪....
受教良多。
我来学习学习的。 别管我。 你们继续。
 

Similar threads

S
回复
0
查看
944
SUNSTONE的Delphi笔记
S
S
回复
0
查看
764
SUNSTONE的Delphi笔记
S
顶部