简体   繁体   English

德尔福的Char和Chr

[英]Char and Chr in Delphi

The difference between Chr and Char when used in converting types is that one is a function and the other is cast 在转换类型时使用的Chr和Char之间的区别在于一个是函数而另一个是强制转换

So: Char(66) = Chr(66) 所以: Char(66) = Chr(66)

I don't think there is any performance difference (at least I've never noticed any, one probably calls the other).... I'm fairly sure someone will correct me on this! 我不认为有任何性能差异(至少我从来没有注意到任何,可能会调用另一个)....我很确定有人会纠正我这个!

EDIT Thanks to Ulrich for the test proving they are in fact identical. 编辑感谢Ulrich的测试证明它们实际上是相同的。
EDIT 2 Can anyone think of a case where they might not be identical, eg you are pushed towards using one over the other due to the context? 编辑2任何人都可以想到它们可能不相同的情况,例如,由于上下文,你被推向使用一个而不是另一个?

Which do you use in your code and why? 你在代码中使用了哪些?为什么?

I did a small test in D2007: 我在D2007做了一个小测试:

program CharChr;

{$APPTYPE CONSOLE}

uses
  Windows;

function GetSomeByte: Byte;
begin
  Result := Random(26) + 65;
end;

procedure DoTests;
var
  b: Byte;
  c: Char;
begin
  b := GetSomeByte;
  IsCharAlpha(Chr(b));
  b := GetSomeByte;
  IsCharAlpha(Char(b));

  b := GetSomeByte;
  c := Chr(b);
  b := GetSomeByte;
  c := Char(b);
end;

begin
  Randomize;
  DoTests;
end.

Both calls produce the same assembly code: 两个调用都生成相同的汇编代码:

CharChr.dpr.19: IsCharAlpha(Chr(b));
00403AE0 8A45FF           mov al,[ebp-$01]
00403AE3 50               push eax
00403AE4 E86FFFFFFF       call IsCharAlpha
CharChr.dpr.21: IsCharAlpha(Char(b));
00403AF1 8A45FF           mov al,[ebp-$01]
00403AF4 50               push eax
00403AF5 E85EFFFFFF       call IsCharAlpha

CharChr.dpr.24: c := Chr(b);
00403B02 8A45FF           mov al,[ebp-$01]
00403B05 8845FE           mov [ebp-$02],al
CharChr.dpr.26: c := Char(b);
00403B10 8A45FF           mov al,[ebp-$01]
00403B13 8845FE           mov [ebp-$02],al

Edit: Modified sample to mitigate Nick's concerns. 编辑:修改样本以减轻尼克的担忧。

Edit 2: Nick's wish is my command. 编辑2:尼克的愿望是我的命令。 ;-) ;-)

The help says: Chr returns the character with the ordinal value (ASCII value) of the byte-type expression, X. * 帮助说: Chr返回字符类型表达式X的序数值(ASCII值)的字符。 *

So, how is a character represented in a computer's memory? 那么,一个角色如何在计算机的记忆中表现出来? Guess what, as a byte*. 猜猜一下,作为一个字节*。 Actually the Chr and Ord functions are only there for Pascal being a strictly typed language prohibiting the use of bytes* where characters are requested. 实际上,Chr和Ord函数仅用于Pascal是一种严格类型的语言,禁止使用字符*来请求字符。 For the computer the resulting char is still represented as byte* - to what shall it convert then? 对于计算机,生成的char仍然表示为byte * - 然后它将转换为什么? Actually there is no code emitted for this function call, just as there is no code omitted for a type cast. 实际上没有为此函数调用发出代码,就像没有为类型转换省略代码一样。 Ergo: no difference. Ergo:没有区别。

You may prefer chr just to avoid a type cast. 你可能更喜欢chr只是为了避免类型转换。

Note: type casts shall not be confused with explicit type conversions! 注意:类型转换不应与显式类型转换混淆! In Delphi 2010 writing something like Char(a) while a is an AnsiChar, will actually do something. 在Delphi 2010中,写一些像Char(a)东西,而a是一个AnsiChar,实际上会做点什么。

**For Unicode please replace byte with integer* **对于Unicode,请用整数替换字节*

Edit: 编辑:

Just an example to make it clear (assuming non-Unicode): 只是一个清楚的例子(假设非Unicode):

var
  a: Byte;
  c: char;
  b: Byte;
begin
  a := 60;
  c := Chr(60);
  c := Chr(a);
  b := a;
end;

produces similar code 产生类似的代码

ftest.pas.46: a := 60;
0045836D C645FB3C         mov byte ptr [ebp-$05],$3c
ftest.pas.47: c := Chr(60);
00458371 C645FA3C         mov byte ptr [ebp-$06],$3c
ftest.pas.48: c := Chr(a);
00458375 8A45FB           mov al,[ebp-$05]
00458378 8845FA           mov [ebp-$06],al
ftest.pas.49: b := a;
0045837B 8A45FB           mov al,[ebp-$05]
0045837E 8845F9           mov [ebp-$07],al

Assigning byte to byte is actually the same as assigning byte to char via CHR(). 将字节分配给字节实际上与通过CHR()将字节分配给char相同。

chr is a function, thus it returns a new value of type char . chr是一个函数,因此它返回char类型的新值。

char(x) is a cast, that means the actual x object is used but as a different type. char(x)是一个强制转换,表示使用实际的x对象但是作为不同的类型。

Many system functions, like inc, dec, chr, ord, are inlined. 许多系统函数,如inc,dec,chr,ord,都是内联的。

Both char and chr are fast. charchr都很快。 Use the one that is most appropriate each time, 使用每次最合适的那个,
and reflects better what you want to do. 并且更好地反映了你想要做的事情。

Chr is function call, it is a bit (tiny-tiny) more expensive then type cast. Chr是函数调用,它比类型转换更有点(微小)。 But i think Chr is inlined by compiler. 但我认为Chr是由编译器内联的。

They are identical, but they don't have to be identical. 他们是相同的,但他们不必须是相同的。 There's no requirement that the internal representation of characters map 1-to-1 with their ordinal values. 不要求字符的内部表示以其序数值映射1对1。 Nothing says that a Char variable holding the value 'A' must hold the numeric value 65. The requirement is that when you call Ord on that variable, the result must be 65 because that's the code point designated for the letter A in your program's character encoding. 没有什么说保持值'A'Char变量必须保持数值65.要求是当你在该变量上调用Ord时,结果必须是65,因为这是为程序字符中的字母A指定的代码点编码。

Of course, the easiest implementation of that requirement is for the variable to hold the numeric value 65 as well. 当然,该要求的最简单实现是变量也保持数值65。 Because of this, the function calls and the type-casts are always identical. 因此,函数调用和类型转换始终是相同的。

If the implementation were different, then when you called Chr(65) , the compiler would go look up what character is at code point 65 and use it as the result. 如果实现不同,那么当你调用Chr(65) ,编译器会查找代码点65处的字符并将其用作结果。 When you write Char(65) , the compiler wouldn't worry about what character it really represents, as long as the numeric result stored in memory was 65. 当你写Char(65) ,编译器不会担心它真正代表什么字符,只要存储在内存中的数字结果是65。

Is this splitting hairs? 这是分裂的头发吗? Yes, absolutely, because in all current implementations, they're identical. 是的,绝对,因为在所有当前的实现中,它们是相同的。 I liken this to the issue of whether the null pointer is necessarily zero. 我把它比作空指针是否必然为零的问题。 It's not, but under all implementations, it ends up that way anyway. 事实并非如此,但在所有实施中,无论如何都会以这种方式结束。

chr is typesafe, char isn't: Try to code chr(256) and you'll get a compiler error. chr是类型安全的,char不是:尝试编码chr(256) ,你会得到一个编译器错误。 Try to code char(256) and you will either get the character with the ordinal value 0 or 1, depending on your computers internal representation of integers. 尝试编写char(256)代码,您将获得序数值为0或1的字符,具体取决于计算机内部的整数表示形式。

I'll suffix the above by saying that that applies to pre-unicode Delphi. 我将通过说这适用于pre-unodeode Delphi来对上述内容进行后缀。 I don't know if chr and char have been updated to take unicode into account. 我不知道是否更新了chr和char以将unicode考虑在内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM