Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi中的Char和Chr_Delphi_Char - Fatal编程技术网

Delphi中的Char和Chr

Delphi中的Char和Chr,delphi,char,Delphi,Char,在转换类型时使用Chr和Char的区别在于一个是函数,另一个是强制转换 所以:Char(66)=Chr(66) 我不认为有任何性能差异(至少我从未注意到任何差异,一个可能会调用另一个)。。。。我确信有人会纠正我的错误 编辑感谢Ulrich的测试,证明它们实际上是相同的。 编辑2是否有人能想到它们可能不完全相同的情况,例如,由于上下文关系,您被迫使用其中一种 您在代码中使用了哪一种?为什么?Chr是函数调用,它比类型转换要贵一点。但我认为Chr是由编译器内联的 我在D2007中做了一个小测试: p

在转换类型时使用Chr和Char的区别在于一个是函数,另一个是强制转换

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

我不认为有任何性能差异(至少我从未注意到任何差异,一个可能会调用另一个)。。。。我确信有人会纠正我的错误

编辑感谢Ulrich的测试,证明它们实际上是相同的。
编辑2是否有人能想到它们可能不完全相同的情况,例如,由于上下文关系,您被迫使用其中一种


您在代码中使用了哪一种?为什么?

Chr是函数调用,它比类型转换要贵一点。但我认为Chr是由编译器内联的

我在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.
两个调用产生相同的汇编代码:

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
编辑:修改样本以缓解Nick的担忧


编辑2:尼克的愿望是我的命令。;-)

chr
是一个函数,因此它返回类型为
char
的新值

char(x)
是一个强制转换,这意味着实际的
x
对象被用作不同的类型

许多系统功能,如inc、dec、chr、ord都是内联的

char
chr
都很快。每次使用最合适的一个,
并且更好地反映您想要执行的操作。

帮助说明:Chr返回带有字节类型表达式X的序号值(ASCII值)的字符*

那么,一个字符在计算机内存中是如何表示的呢?猜猜看,作为一个字节*。事实上,Chr和Ord函数仅适用于Pascal,因为Pascal是一种严格类型化的语言,禁止在请求字符时使用字节*。对于计算机来说,生成的字符仍然表示为字节*-那么它将转换成什么?实际上,这个函数调用没有发出任何代码,就像类型转换没有省略任何代码一样。因此:没有区别

为了避免类型转换,您可能更喜欢
chr

注意:类型转换不能与显式类型转换混淆!在Delphi2010中,编写类似于
Char(a)
的东西,而a是AnsiChar,实际上会做一些事情

**对于Unicode,请将字节替换为整数*

编辑:

仅举一个例子(假设非Unicode):

生成类似的代码

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

将字节分配给字节实际上与通过CHR()将字节分配给字符是相同的。

它们是相同的,但不必相同。不要求字符的内部表示形式与其序号值一一对应。没有任何规定表明,持有值
'a'
Char
变量必须持有数值65。要求是,当您对该变量调用
Ord
时,结果必须是65,因为这是程序字符编码中为字母A指定的代码点

当然,实现该要求的最简单方法是让变量也保持数字值65。因此,函数调用和类型转换总是相同的

如果实现不同,那么当您调用
Chr(65)
时,编译器将查找代码点65处的字符并将其用作结果。当您编写
Char(65)
时,只要存储在内存中的数字结果是65,编译器就不会担心它真正代表什么字符


这是在吹毛求疵吗?是的,绝对如此,因为在所有当前的实现中,它们都是相同的。我把这比作空指针是否一定为零的问题。不是,但在所有实现中,它都是这样结束的。

chr是类型安全的,char不是:尝试编写
chr(256)
,您将得到一个编译器错误。尝试对字符(256)进行编码,您将获得序号值为0或1的字符,具体取决于计算机内部的整数表示形式


我将在上面加上后缀,表示这适用于unicode之前的Delphi。我不知道chr和char是否已经更新为考虑unicode。

这似乎是作弊。尝试使用变量而不是常量。如果你得到同样的结果,我会给你的答案加1,如果你测试
ch:=chr(b);ch:=char(b)这将是完美的。如果它们都相同。。。(他们似乎是这样的),那么你怎么能判断哪一个是合适的呢,这更像是“你当时喜欢哪一个”?@JamesB,我没说他们是一样的
chr
是一个函数。但在大多数情况下,它们可以被视为相同的。Chr不返回新值,而是返回作为参数给定的表达式的结果。在调用chr之前对表达式求值,而对chr的调用完全没有任何作用。@Uwe Raabe,可以,但该临时值(表达式的求值)是返回值,否?它们大部分是内置的,因为在系统单元中没有对它们的定义。与单纯的内联函数稍有不同。使用Char而不是Chr的一种情况是,如果您正在进行显式转换,例如从AnsiChar进行转换。。感谢Uwe RaabeIt,它看起来像是一个重复功能的案例,可能是因为历史原因。类似于“原始版本被称为Chr(),但后来有人说,如果我们称它为Char(),这会更有意义,因为它基本上是一个字符的类型转换,但我们不能更改它,因为有很多现有代码使用Chr(),这会破坏它,所以我们将把它们都放进去。”这只是一个猜测,但这可能与实际情况非常接近。Jensen/Wirth的原始Pascal已经有了一个Chr()函数,但没有类型强制转换。它们不适合语言设计。我知道,字符只是一个例子。ORD()还将仅返回内部整数表示形式
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