关于进制转换的一些问题,高分相送但求解释 ( 积分: 300 )

  • 主题发起人 主题发起人 app2001
  • 开始时间 开始时间
A

app2001

Unregistered / Unconfirmed
GUEST, unregistred user!
最近在搞一个进制转换的函数,弄来弄去转不出弯来,哪位有识之士帮帮忙????
事情是这样的,我手上有一个VC的源码,是一个DLL中的函数,本意是想自己仿一个出来调用方便些,不用每次都为了这个功能调用那个DLL了.函数如下:
__int16 __stdcall hex_asc(unsigned char *hex,unsigned char *asc,long length)
{
UCHAR hLowbit,hHighbit;
long i;
for(i=0;i<length*2;i=i+2)
{
hLowbit=hex[i/2]&amp;0x0f;
hHighbit=hex[i/2]/16;
if(hHighbit>=10)
asc=hHighbit+'7';
else
asc=hHighbit+'0';
if(hLowbit>=10)
asc[i+1]=hLowbit+'7';
else
asc[i+1]=hLowbit+'0';
}
asc[length*2]='/0';
return 0;
}
我想仿一个一样的D版函数出来

function hex_asc1(hex, asc: PCHAR
len: LongInt): Integer;
var
hLowbit, hHighbit : Byte;
i : LongInt;
begin
i := 0;
while i < len * 2 do
begin
hLowbit := Integer(hex[i div 2]) and $F;
hHighbit := Integer(hex[i div 2]) div 16;
if hHighbit >= 10 then
asc := Char(hHighbit + Byte(#37))
else
asc := Char(hHighbit + Byte(#30));
if hLowbit >= 10 then
asc[i + 1] := Char(hLowbit + Byte(37))
else
asc[i + 1] := Char(hLowbit + Byte(30));
i:=i+2;
end;
asc[len * 2] := #0;
end;

但在实际调用中,发现我调用这个仿制出来的函数所得到的结果和调用上述VC函数所得到的结果是不一样的.
调用方式:
GetMem(sasc, 100);
try
hex_asc(pchar(pData),sasc,DLen)

value := sasc+' tt '+StrToAsc(pchar(pData),DLen)

finally
FreeMem(sasc);
end;
正常调用结果应该为:3BFF1100,但我那个仿VC的函数得出来的是:!044&amp;not;&amp;not

然后呢,我又查找资料和请教了一些朋友得到了如下函数:
function hex_asc2 (StrString: string
Len: Integer): string

var
i : integer;
tempstr : string;
begin
Result := '';
tempstr := Ansiuppercase(trim (StrString))

if tempstr = '' then
exit;
for i := 1 to Len do
Result := Result + inttohex(Ord(StrString), 2);
end;


function hex_asc3(src: string
Len: Integer): string;
var
i: Integer;
begin
SetLength(Result, 2 * Len);
for i:= 1 to Len do
begin
Result[i * 2 - 1]:= ByteToChar((Byte(src) and $f0) shr 4);
Result[i * 2]:= ByteToChar(Byte(src) and $0f);
end;
end;

function ByteToChar(N: Byte): Char;
begin
if N in [0..9] then
Result := Chr(48 + N)
else
if N in [10..15] then
Result := Chr(55 + N)
else
Result := Chr(255);
end;

这两个函数呢,在一定的情况下,调用后得到的结果和DLL中是一样的,但也不完全是一样的,又回到刚才那个调用情况:
GetMem(sasc, 100);
try
hex_asc(pchar(pData), sasc, SizeOf(pData));

value := sasc+' '+ hex_asc2(pchar(pData)) +' '+ hex_asc3(pchar(pData));
finally
FreeMem(sasc);
end;
这么调用得到的三个结果是
复位应答字节串: 3BFF1100 3BFF11 3BFF11
第一个是DLL中调用得回的正确结果
后面两个函数则得不到最后两个零

最后请教了朋友,改进如下:
function hex_asc2(StrString: PChar
Len: Integer): string;
var
i : integer;
tempstr : string;
begin
Result := '';
tempstr := Ansiuppercase(string(StrString))

if tempstr = '' then
exit;
for i := 0 to Len - 1 do
Result := Result + inttohex(Ord(StrString), 2);
end;

function hex_asc3 (src: PChar
Len: Integer): string;
var
i : integer;
begin
SetLength(Result, 2 * Len);
for i := 0 to Len - 1 do
begin
Result[i * 2 + 1] := ByteToChar((Byte(src^) and $F0) shr 4);
Result[i * 2 + 2] := ByteToChar(Byte(src^) and $0F);
Inc(src);
end;
end;

这样才得到和DLL中的VC函数一样的正确结果出来,结果虽然是完成了,但我还很是糊涂,想请各位有识之士给我好好总结一下.
1、 为什么我仿VC的那个函数hex_as1得不到正确结果,是哪一步没有转换过来时正确呢?
2、 为什么hex_asc2和hex_asc3在参数为String时,转换回来的结果不完全正确,换为Pchar类型后就正常了呢?
3、 hex_asc2和hex_asc3实现的方式不是很相同,但结果是一样的,这两个函数的实现原理是什么样的呢,烦请解释?

最后我还有一个再反转换回去的VC函数
这题单独另开贴给200分,烦请再给做一个能达到同样功能的D版函数
__int16 __stdcall asc_hex(unsigned char *asc, unsigned char *hex, long pair_len)
{
char src1,src2;
int len;
for (len=0
len < pair_len
len++)
{
src1 = *(asc+len*2);
src2 = *(asc+len*2+1);
if ((src1>='0') &amp;&amp
(src1<='9'))
src1=src1-'0';
else if ((src1>='A') &amp;&amp
(src1<='F'))
src1=src1-'A'+10;
else if ((src1>='a') &amp;&amp
(src1<='f'))
src1=src1-'a'+10;
else
return -1;
if ((src2>='0') &amp;&amp
(src2<='9'))
src2=src2-'0';
else if ((src2>='A') &amp;&amp
(src2<='F'))
src2=src2-'A'+10;
else if ((src2>='a') &amp;&amp
(src2<='f'))
src2=src2-'a'+10;
else
return -1;
*hex++ = (src1 << 4) | src2

}
return 0;
}
 
最近在搞一个进制转换的函数,弄来弄去转不出弯来,哪位有识之士帮帮忙????
事情是这样的,我手上有一个VC的源码,是一个DLL中的函数,本意是想自己仿一个出来调用方便些,不用每次都为了这个功能调用那个DLL了.函数如下:
__int16 __stdcall hex_asc(unsigned char *hex,unsigned char *asc,long length)
{
UCHAR hLowbit,hHighbit;
long i;
for(i=0;i<length*2;i=i+2)
{
hLowbit=hex[i/2]&amp;0x0f;
hHighbit=hex[i/2]/16;
if(hHighbit>=10)
asc=hHighbit+'7';
else
asc=hHighbit+'0';
if(hLowbit>=10)
asc[i+1]=hLowbit+'7';
else
asc[i+1]=hLowbit+'0';
}
asc[length*2]='/0';
return 0;
}
我想仿一个一样的D版函数出来

function hex_asc1(hex, asc: PCHAR
len: LongInt): Integer;
var
hLowbit, hHighbit : Byte;
i : LongInt;
begin
i := 0;
while i < len * 2 do
begin
hLowbit := Integer(hex[i div 2]) and $F;
hHighbit := Integer(hex[i div 2]) div 16;
if hHighbit >= 10 then
asc := Char(hHighbit + Byte(#37))
else
asc := Char(hHighbit + Byte(#30));
if hLowbit >= 10 then
asc[i + 1] := Char(hLowbit + Byte(37))
else
asc[i + 1] := Char(hLowbit + Byte(30));
i:=i+2;
end;
asc[len * 2] := #0;
end;

但在实际调用中,发现我调用这个仿制出来的函数所得到的结果和调用上述VC函数所得到的结果是不一样的.
调用方式:
GetMem(sasc, 100);
try
hex_asc(pchar(pData),sasc,DLen)

value := sasc+' tt '+StrToAsc(pchar(pData),DLen)

finally
FreeMem(sasc);
end;
正常调用结果应该为:3BFF1100,但我那个仿VC的函数得出来的是:!044&amp;not;&amp;not

然后呢,我又查找资料和请教了一些朋友得到了如下函数:
function hex_asc2 (StrString: string
Len: Integer): string

var
i : integer;
tempstr : string;
begin
Result := '';
tempstr := Ansiuppercase(trim (StrString))

if tempstr = '' then
exit;
for i := 1 to Len do
Result := Result + inttohex(Ord(StrString), 2);
end;


function hex_asc3(src: string
Len: Integer): string;
var
i: Integer;
begin
SetLength(Result, 2 * Len);
for i:= 1 to Len do
begin
Result[i * 2 - 1]:= ByteToChar((Byte(src) and $f0) shr 4);
Result[i * 2]:= ByteToChar(Byte(src) and $0f);
end;
end;

function ByteToChar(N: Byte): Char;
begin
if N in [0..9] then
Result := Chr(48 + N)
else
if N in [10..15] then
Result := Chr(55 + N)
else
Result := Chr(255);
end;

这两个函数呢,在一定的情况下,调用后得到的结果和DLL中是一样的,但也不完全是一样的,又回到刚才那个调用情况:
GetMem(sasc, 100);
try
hex_asc(pchar(pData), sasc, SizeOf(pData));

value := sasc+' '+ hex_asc2(pchar(pData)) +' '+ hex_asc3(pchar(pData));
finally
FreeMem(sasc);
end;
这么调用得到的三个结果是
复位应答字节串: 3BFF1100 3BFF11 3BFF11
第一个是DLL中调用得回的正确结果
后面两个函数则得不到最后两个零

最后请教了朋友,改进如下:
function hex_asc2(StrString: PChar
Len: Integer): string;
var
i : integer;
tempstr : string;
begin
Result := '';
tempstr := Ansiuppercase(string(StrString))

if tempstr = '' then
exit;
for i := 0 to Len - 1 do
Result := Result + inttohex(Ord(StrString), 2);
end;

function hex_asc3 (src: PChar
Len: Integer): string;
var
i : integer;
begin
SetLength(Result, 2 * Len);
for i := 0 to Len - 1 do
begin
Result[i * 2 + 1] := ByteToChar((Byte(src^) and $F0) shr 4);
Result[i * 2 + 2] := ByteToChar(Byte(src^) and $0F);
Inc(src);
end;
end;

这样才得到和DLL中的VC函数一样的正确结果出来,结果虽然是完成了,但我还很是糊涂,想请各位有识之士给我好好总结一下.
1、 为什么我仿VC的那个函数hex_as1得不到正确结果,是哪一步没有转换过来时正确呢?
2、 为什么hex_asc2和hex_asc3在参数为String时,转换回来的结果不完全正确,换为Pchar类型后就正常了呢?
3、 hex_asc2和hex_asc3实现的方式不是很相同,但结果是一样的,这两个函数的实现原理是什么样的呢,烦请解释?

最后我还有一个再反转换回去的VC函数
这题单独另开贴给200分,烦请再给做一个能达到同样功能的D版函数
__int16 __stdcall asc_hex(unsigned char *asc, unsigned char *hex, long pair_len)
{
char src1,src2;
int len;
for (len=0
len < pair_len
len++)
{
src1 = *(asc+len*2);
src2 = *(asc+len*2+1);
if ((src1>='0') &amp;&amp
(src1<='9'))
src1=src1-'0';
else if ((src1>='A') &amp;&amp
(src1<='F'))
src1=src1-'A'+10;
else if ((src1>='a') &amp;&amp
(src1<='f'))
src1=src1-'a'+10;
else
return -1;
if ((src2>='0') &amp;&amp
(src2<='9'))
src2=src2-'0';
else if ((src2>='A') &amp;&amp
(src2<='F'))
src2=src2-'A'+10;
else if ((src2>='a') &amp;&amp
(src2<='f'))
src2=src2-'a'+10;
else
return -1;
*hex++ = (src1 << 4) | src2

}
return 0;
}
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=13396
 
哦,兄弟,程序我有,解决方法也出来了,只是但求解释个明白而已.
 
1.笔误?'7','0'的Ord值是0x37,0x30,而非37,30。用Byte('7')就不会有此问题啦
2.没发现你说的情况,结果相同。
3.一个直接用IntToHex转换,另外一个通过移位对应查找的方式,与VC的代码原理相同的
 
几位高手都在,偷偷滴把代码放上来,等着明天出丑



function hex_asc(hex: PChar
asc: PChar
length: Longint): Integer;
var
hLowbit, hHighbit: UCHAR;
I : LongInt;
begin
I := 0;
while I < Length * 2 -1 do begin
hLowbit := Integer(hex + i div 2) and $0f;
hHighbit := Integer(hex + i div 2) div 16;
if(hHighbit >= 10) then asc := Chr(hHighbit + Ord('7'))
else asc := Chr(hHighbit + Ord('0'));

if(hLowbit >= 10) then asc[i+1] := Chr(hLowbit + Ord('7'))
else asc[i+1] := Chr(hLowbit + Ord('0'));

Inc(I, 2);
end;
asc[length*2] := #0;
Result := 0;
end;
 
反转函数:
这个是VC代码直接转的,其实可以写得更简洁些,如if src1 in ['0'..'9'] then 这样测试src1在什么范围等,懒得烦神啦
function asc_hex(asc, hex: PChar
pair_len: Longint): Integer;
var
src1, src2: Char;
len: Integer;
begin
Result := -1;
for len := 0 to pair_len - 1 do
begin
src1 := asc[len*2];
src2 := asc[len*2+1];
if ((src1>='0') and (src1<='9')) then
src1:=Char(Byte(src1)-Byte('0'))
else if ((src1>='A') and (src1<='F')) then
src1:=Char(Byte(src1)-Byte('A')+10)
else if ((src1>='a') and (src1<='f')) then
src1:=Char(Byte(src1)-Byte('a')+10)
else Exit;
if ((src2>='0') and (src2<='9')) then
src2:=Char(Byte(src2)-Byte('0'))
else if ((src2>='A') and (src2<='F')) then
src2:=Char(Byte(src2)-Byte('A')+10)
else if ((src2>='a') and (src2<='f')) then
src2:=Char(Byte(src2)-Byte('a')+10)
else Exit;
hex^ := Char((Byte(src1) shl 4) or Byte(src2));
Inc(hex);
end;
Result := 0;
end;

下面这个比较简洁些:
function asc_hex2(const S: string): string;
var
I: Integer;
begin
Result := '';
for I := 1 to Length(S) div 2 do
Result := Result + Char(StrToInt('$' + S[I*2-1] + S[I*2]));
end;
 
乘是老大的帖子,俺把俺不懂的地方提出来,希望大家伙都帮俺看看
C里面的unsigned char在Delphi直译应该是Word类型,那么hex自然就是PWord类型了,asc同理,long就对应LongInt类型

而hex[i/2]&amp;0x0f;是把hex为基准的指针地址加 i div 2以后的位置和 16进制的0f与,把结果赋值给hLowbit,但是我这样理解应该是错的,UChar在Delphi里面定义在Window单元里面,和Byte是一样的,是无符号8bit整形,在0..255。但是地址应该不会只小于255,其一。
其二,没记错的话,C里面的''这个东西应该Delphi的Ord同理,那么也就是
asc=hHighbit+'7';这里的作用是asc下移i位的指针地址换了,换成了hHighbit+ ord('7'),所以我的理解是通过变换asc里面的各个项的指针地址,但是不改变指向的值来达到置位的目的

上面是我的理解,我想应该是不合理的,关键是和C里面的指针的这个变换关系,哪位大虾告知一声,重金酬谢


__int16 __stdcall hex_asc(unsigned char *hex,unsigned char *asc,long length)
{
UCHAR hLowbit,hHighbit;
long i;
for(i=0;i<length*2;i=i+2)
{
hLowbit=hex[i/2]&amp;0x0f;
hHighbit=hex[i/2]/16;
if(hHighbit>=10)
asc=hHighbit+'7';
else
asc=hHighbit+'0';
if(hLowbit>=10)
asc[i+1]=hLowbit+'7';
else
asc[i+1]=hLowbit+'0';
}
asc[length*2]='/0';
return 0;
}
 
1.unsigned char,顾名思义,也就是无符号的char字符型,C语言中char是有符号的(-128..127),unsigned char的范围就是0..255,当然就是Byte啰
2.“C里面的''这个东西应该Delphi的Ord同理”,C的表达式中类型检查没有Delphi这么严格,字符'7'这样的,可以作为字符,也可以直接作为数值进行运行的,比较随意的,而不是说''这个东东有什么特殊的意义,和Ord类似。“asc=hHighbit+'7';这里的作用是asc下移i位的指针地址换了”,没看懂你是什么意思,就说说我的看法啦。C中数组名实际上就是指针,指针也可以按照数组方式访问,对于char* asc指针,asc就是访问第i+1个字符,读写的都是字符的内容,似乎用不着扯上“指针地址”,尽管它实际上的确是存放在asc的地址+i的内存单元。至于“通过变换asc里面的各个项的指针地址,但是不改变指向的值来达到置位的目的”这就更看得晕乎啦[:D]
 
看来还是我没有理解透,我刚刚的意思是这样的,一个数组,里面的东西不动,但是指向她们的指针地址变了,还是不对,我想成是通过指向数组元素的指针变换,也就是地址变换来达到数组中数据位置变换,不过听楼上一说我自己也晕了,byte那个倒是可以理解了,不知道哪里找了资料说是word,糊涂糊涂,继续批评,我其实很想知道直译那段代码为什么会结果不对,想有一个直译的代码参考
 
哈哈,原因其实我前面讲了,楼主的把'7'的Ord值搞成37了,其实是16进制的0x37呢,看看下面的
function hex_asc(hex, asc: PChar
length: Longint): Integer;
var
hLowbit, hHighbit: Byte;
i: Integer;
begin
i := 0;
while i < length*2 do
begin
hLowbit := Integer(hex[i div 2]) and $0f;
hHighbit := Integer(hex[i div 2]) div 16;
if (hHighbit>=10) then
asc := Char(hHighbit+Byte('7'))
else
asc := Char(hHighbit+Byte('0'));
if (hLowbit>=10) then
asc[i+1] := Char(hLowbit+Byte('7'))
else
asc[i+1] := Char(hLowbit+Byte('0'));
Inc(I, 2);
end;
asc[length*2]:=#0;
Result := 0;
end;
 
原来如此,感谢感谢,明天等app大虾测过之后马上给分
 
1.如lichengbin所说.
3.条条大路通罗马,自是别有洞天,风景各异.
2.这个因为你在调用的时候hex_asc2(pchar(pData)) 没有跟出完整形式,这个就不好说了.不过要记得PChar应该是从 0<->Len-1 而string是从 1<->Len

还有,适当的变换代码写法,可以使代码更容易看懂。比如
function ByteToChar(N: Byte): Char;
begin
if N in [0..9] then
Result := Chr(48 + N)
else
if N in [10..15] then
Result := Chr(55 + N)
else
Result := Chr(255);
end;
转换成下边的看齐来显得更加简洁
function ByteToChar(N: Byte): Char;
begin
case N of
$0..$9: Result:= Chr(N - $0 + Ord('0'));
$A..$F: Result:= Chr(N - $A + Ord('A'));
else
Result := Chr($FF);
end;

下边是我使用的:
function StrToHex(src : string) : string;
inline function ByteToHexChar(val : Byte): Char;
begin
case val of
$0..$9: Result:= Chr(Ord('0') -$0 + val);
$A..$F: Result:= Chr(Ord('A') -$A + val);
else
raise Exception.Create('ERROR IN ByteToHexChar()');
end;
end;
var
len: Integer;
iPos : Integer;
begin
Result:= '';
len:= Length(src);
SetLength(Result, 3*len);

for iPos:=1 to len do
begin
Result[iPos*3-2]:= ByteToHexChar(Ord(src[iPos]) div $10);
Result[iPos*3-1]:= ByteToHexChar(Ord(src[iPos]) mod $10);
Result[iPos*3-0]:= ' ';
end;
end;
对于使用IntToHex/StrToInt($+..)这样的基本持反对态度,因为其效率低,而且更主要的是这个思路我不喜欢.

反转
function HexStrToValStr(pAsc, pHex: PChar
pair_len: Longint): Integer;
inline function HexCharToValByte(ch : Char) : Byte;
begin
case ch of
'0'..'9': Result:= Ord(ch)-Ord('0');
'a'..'f': Result:= Ord(ch)-Ord('a')+10;
'A'..'F': Result:= Ord(ch)-Ord('A')+10;
else
raise Exception.Create('Invalid parameter in &quot;function HexCharToValue(ch : Char) : Byte&quot;');
end;
end;
var
iPos: Integer;
begin
Result := -1;
for iPos := 0 to pair_len - 1 do
begin
pHex^:= Chr(HexCharToValByte(pAsc[iPos]) * $10 + HexCharToValByte(pAsc[iPos+1]));
Inc(pHex, 2);
end;
Result := 0;
end;
 
to zjan521
你以为你这两句效率高吗?
Result[iPos*3-2]:= ByteToHexChar(Ord(src[iPos]) div $10);
Result[iPos*3-1]:= ByteToHexChar(Ord(src[iPos]) mod $10);
 
关于1个问题,lichengbin果然是一语中的,慧眼识BUG啊,一百分是你的了.
关于2个问题,如zjan521说:&quot;这个因为你在调用的时候hex_asc2(pchar(pData)) 没有跟出完整形式&quot;;是这样的,pData回来的是个pointer的无类型指针值.所以我需要这么换一下的,如lichengbin所说的结果一样,但我反复试了,还真不一样哦,其结果犹其在不指定长度的形式下调用函数时,更明显的会反映的结果是不一样的,如上调用
GetMem(sasc, 100);
try
hex_asc(pchar(pData),sasc,DLen)
//Vc动态库里函数的调用
value := sasc+' '+hex_asc3(string(pchar(pData)),DLen)

finally
FreeMem(sasc);
end;
在这其中Dlen是没有明确指名长度的,只是定义了其为整形,在没有赋初值的情况下,调用后得到的结果如下:
复位应答字节串: 3BFF1100021080206000178638030102534394171111
3BFF11003602000010E94200D81B4A01A0634A010000
但如果 DLen:=SizeOf(pData);的情况下,得到的结果就是一样的了
复位应答字节串: 3BFF1100 3BFF1100
这个是什么原因才导致这样的情况发生的呢???
关于第3个问题,二个函数的最终结果是一样的,但单从代码上看,hex_asc2是要比hex_asc3精简一些的,从效率上来说,又是哪个更优呢?如如zjan521说&quot;对于使用IntToHex/StrToInt($+..)这样的基本持反对态度,因为其效率低&quot;指的是inttohex(Ord(StrString), 2);吗??原因是什么??还有hex_asc2函数中先调用了Ansiuppercase函数,但经我注释掉它后,发现结果并没有改变,那这个函数还有没有必要呢?

关于反转函数,还没来得及测试,测度后会公布结果,再开贴放分,另还要特别感谢chenybin兄的参与,他帮我提了许多我也想了解的细节(我也会给你另开贴放分的),使我能更详细的了解到各中的缘委,嘿,还是那句话,问题是解决了的,就是还没想明白,想总结一下,但求解释清晰明了,如果满意的,最后再开贴放分.我仍等大家的解答.麻烦大家了.谢谢
 
欢迎加入Borland 一线程序员,参与群里技术讨论!欢迎女孩子,也欢迎男孩子参与技术讨论!群号15154361
 
C译出的整套函数

function hex_asc(hex, asc: PChar
length: Longint): Integer;
var
hLowbit, hHighbit: Byte;
i: Integer;
begin
i := 0;
while i < length*2 do
begin
hLowbit := Integer(hex[i div 2]) and $0f;
hHighbit := Integer(hex[i div 2]) SHR 4;
if (hHighbit>=10) then
asc := Char(hHighbit+Byte('7'))
else
asc := Char(hHighbit+Byte('0'));
if (hLowbit>=10) then
asc[i+1] := Char(hLowbit+Byte('7'))
else
asc[i+1] := Char(hLowbit+Byte('0'));
Inc(I, 2);
end;
Result := 0;
end;

function asc_hex(asc, hex:PChar
pair_len:Longint):Integer;
var
src1,src2:byte;
len:Integer;
begin
for len:=0 to pair_len-1 do
begin
char(src1) := pchar(dword(asc)+len*2)^;
char(src2) := pchar(dword(asc)+len*2+1)^;
if src1 in [$30..$39] then //'0'=$30
src1:=src1-$30
else if src1 in [$41..$46] then //'A'=$41
src1:=src1-$41+10
else if src1 in [$61..$66] then //'a'=$61
src1:=src1-$61+10
else
Result := -1;
if src2 in [$30..$39] then //'0'=$30
src2:=src2-$30
else if src2 in [$41..$46] then //'A'=$41
src2:=src2-$41+10
else if src2 in [$61..$66] then //'a'=$61
src2:=src2-$61+10
else
Result := -1;
hex[len] := char((src1 shl 4) or src2);
end;
Result := 0;
end;

测试
procedure TForm1.Button1Click(Sender: TObject);
var
s,s2:array[0..3] of char;
s1:array[0..7] of char;
begin
s:='1234';
hex_asc(s,s1,4);
showmessage(s1);
asc_hex(s1,s2,4);
showmessage(s2);
end;
 
关于第2个问题,如果不传递DLen参数,结果难以预料,因为函数中你循环需要用到它,结果如何就看DLen的长度啦,如果函数中有个DLen := Length(SrcString)或者DLen := StrLen(SrcString)的,那就另当别论啦,不过那样,也应该是传递string的结果正确,PChar,字符串中的#0被当作结束符,3BFF1100就不会有后面的00,而string中是可以容纳#0的。
“但如果 DLen:=SizeOf(pData);的情况下,得到的结果就是一样的了
复位应答字节串: 3BFF1100 3BFF1100”
这正说明了传递DLen的必要性!
至于用IntToHex/StrToInt效率的确比直接转换低很多,大概时间是3-4倍吧,从IntToHex的实现上可以看到,它多作了很多处理很函数调用,其实转换原理跟直接转换也是差不多的。对于数据量不是特别大、效率要求不是特别高的话,也没必要如此计较,比较代码更简洁明了应该是追求的更高目标,更利于代码维护,用IntToHex至少可以保证其正确性,不会因为如楼主这样的笔误而造成结果不对且耗时耗力的情况。
另外,pData是什么东东?SizeOf(pData),如果是array[0..n] of Char没问题,如果是PChar、string,那可就不对啰[:D]
 
另外,pData是什么东东?它是个pData是个pointer的无类型指针值啊,
如果不传递DLen参数,结果难以预料,因为函数中你循环需要用到它,结果如何就看DLen的长度啦,但为什么VC动态库中函数和用字符串做为参数的函数得出来的结果不一样呢???
 
//来自:41426277, 时间:2005-9-2 9:16:06, ID:3188791
//你以为你这两句效率高吗?
这样写
1.直观易读,
2.在DELPHI中引入了inline,因此其效率不会比写一大堆的if低到哪里去。
3.我并不是极限追求效率的,如果极限追求,我会使用汇编嵌入,不过好像没有这种需求.一般的使用需求,没必要为了丁点效率降低可读性,这两者之间是需要权衡的
4.比如说到直观, ch + Ord('7') 和 ch + Ord('A') - 10;两个的汇编代码是一样的,可是可读性不同.效率不光指CPU,人的效率是最关键的.我不赞成IntToStr这样的操作,因为这样不仅CPU效率低,也降低了人思考的效率.
 
后退
顶部