Compares two strings with case sensitivity. function StrComp(const Str1, Str2: PChar): Integer; assembler; asm PUSH EDI PUSH ESI MOV EDI,EDX MOV ESI,EAX MOV ECX,0FFFFFFFFH XOR EAX,EAX REPNE SCASB NOT ECX MOV EDI,EDX XOR EDX,EDX REPE CMPSB MOV AL,[ESI-1] MOV DL,[EDI-1] SUB EAX,EDX POP ESI POP EDI end;
另外windows提供的字符串比较接口,参见msdn function CompareString; external kernel32 name 'CompareStringA'; function CompareStringA; external kernel32 name 'CompareStringA'; function CompareStringW; external kernel32 name 'CompareStringW';
| 4字节引用计数 |
+++++++++++++++++++++++++++++++++
| 4字节长度 |
+++++++++++++++++++++++++++++++++
| ...不定长度字符串... |
+++++++++++++++++++++++++++++++++
| #0 |
+++++++++AnsiString实际上是指向字符串结构的指针。
| 4字节分配的大小 |
++++++++++++++++++++++++++++++++
| 4字节引用计数 |
+++++++++++++++++++++++++++++++++
| 4字节长度 |
+++++++++++++++++++++++++++++++++
| ...不定长度字符串... |
+++++++++++++++++++++++++++++++++
| #0 |
+++++++++
sorry,应该是上面的格式
所以每次用sizeof(string)得到的值总是4
这里的4位应该是4个字节吧,不然无法表示2G长度的字符串
对于大量,复杂的字符串操作,用object pascal可以写出比c/c++快几十倍的程序.
MOVS 传送字节或字的字符串指令
CMPS 比较字节或字的字符串指令
SCAS 扫描字节或字的字符串指令
LODS 取字节或字的字符串指令
STOS 存字节或字的字符串指令
其循环由cpu自己完成,因此速度非常快。
比如
SCAS指令(串搜索指令)
格式: SCAS 目标串
或 SCASB/SCASW
功能: 在ES:[DI]指向的目标串中查找AX或AL指定的内容,并按照 DF来修改DI的内容,使其指向目标串的下一单元。
其查找的方法是: 用AX或AL的内容减去ES:[DI]指向的单元内容,结果反映在状态标志位上。
为了在一个串中查找一个指定的字符,要ES:DI指向串首,要找的字符放在AL,
而串的长度放在CX寄存器中,然后在SCAS指令前加上重复前缀REPNZ来进行。
当查找结束时,如果ZF=1,则说明是找到了字符而结束查找(DI-1指向的位置为该字符的位置),
否则ZF=0,说明找不到该字符。
function CompareStr(const S1, S2: string): Integer; assembler;
asm
PUSH ESI //ESI压栈
PUSH EDI //EDI压栈
MOV ESI,EAX
MOV EDI,EDX
//========= 取S1长度到EAX =====================
OR EAX,EAX //EAX是否为0 (空字符串)
JE @@1 //为0则跳转(ZF=1)
MOV EAX,[EAX-4]//取S1长度到EAX
//========= 取S2长度到EDX =====================
@@1: OR EDX,EDX //EDX是否为0
JE @@2 //为0则跳转(ZF=1)
MOV EDX,[EDX-4]//取S2长度到EDX
//========= ECX存放最小长度 =====================
@@2: MOV ECX,EAX
CMP ECX,EDX //比较ECX,EDX
JBE @@3 //小于等于则跳转(CF=1 or ZF=1)
MOV ECX,EDX //ECX存放最小长度
//========= 开始比较 =====================
@@3: CMP ECX,ECX //ZF:=1 ?? CLD //DF:=0 need?
REPE CMPSB //相等则重复取
JE @@4 //CX计数用完了仍然相等
MOVZX EAX,BYTE PTR [ESI-1] //= xor EAX, EAX ; MOV EAX,BYTE PTR [ESI-1] 清0以后MOV //源串的当前字符进EAX
MOVZX EDX,BYTE PTR [EDI-1] //目标串的当前字符进EDX
@@4: SUB EAX,EDX //如果字符串前面都相同的话返回长度差,否则返回第一个不同的字符的差
POP EDI //EDI出栈
POP ESI //ESI出栈
end;
你最后的结论
“总结,Delphi对字符进行比较就是调用上面的函数,所以可以看出,Delphi处理4的倍数个字符的速度最快”
对于现在的cpu来说速度快与否根本决不出来...拿它来当研究生论文或许可以,但是我觉得现实意义并不大。
你说的话很有道理,但是这正好证明了一点,我们这一代的程序员,不如Dos那批程序员了。个人观点:
学习编程我认为要往下面学,不学习底层,很难成为优秀的程序员,如果每天最求新的技术,你的水平很难有实质进展。应为所有的突破性的技术一般都要几十年才可以更新。其他的时候都是在基础上发挥而已。计算机水平同样也是,你的程序为什么写得比别人好,不是应为
某个技术,而是在方方面面都领先了。
存中的确切格式如下:
(4字节)分配大小+(4字节)引用计数+(4字节)字串长度+(不定长)字符数组+(1
字节)$0结束字符我个人很不喜欢,我最初学的是VB,好象也和这差不多,但我比较认可VC的字符串,因为DELPHI好多函数返回的,STRING不能放ARRAY OF CHAR 里,但VC 的STRING 就不会有这麻烦,其实就是S[]谁能给出DELPHI中STRING=》ARRAY [] OF CHAR 的解决方案啊?
s: string;
ary: array of char;
begin
s := 'Hello World';
setlength(ary,length(s));
copymemory(@ary[0],@s[1],length(s));
showmessage(ary[0]);
你说Dephi内部的处理函数啊,好,要等我有时间去研究一下.
array of char与字符串相转换一般只在函数调用时才会使用。
function f(a:array of char)
...
var s:string;
可以使用调用 f(s[1])直接调用。
无条件送您50元,人人有份!
网址: http://chinaour.com/?puker
function StrComp(const Str1, Str2: PChar): Integer; assembler;
asm
PUSH EDI
PUSH ESI
MOV EDI,EDX
MOV ESI,EAX
MOV ECX,0FFFFFFFFH
XOR EAX,EAX
REPNE SCASB
NOT ECX
MOV EDI,EDX
XOR EDX,EDX
REPE CMPSB
MOV AL,[ESI-1]
MOV DL,[EDI-1]
SUB EAX,EDX
POP ESI
POP EDI
end;
function CompareString; external kernel32 name 'CompareStringA';
function CompareStringA; external kernel32 name 'CompareStringA';
function CompareStringW; external kernel32 name 'CompareStringW';
在TTable或TQuery查询字段re(varchar 1000)为什么得到的长度只有255;
TQuery.FieldByName('re').asstring得到的只能是string
但怎么样才取得全部的字段数据(超过255)??
| 4字节分配的大小 |
++++++++++++++++++++++++++++++++
| 4字节引用计数 |
+++++++++++++++++++++++++++++++++
| 4字节长度 |
+++++++++++++++++++++++++++++++++
| pchar 4字节指针(char *) |
+++++++++++++++++++++++++++++++++
..................
pchar ->不定长度字符串#0
pchar(AnsiString) 其实就是返回上面的pchar指针
day day upup
up
up
hillbilly(一键倾城)
哈哈,同感,学习10年,更做过10年项目的人更不就不能比。你说呢