2010-03-19 1 views
4

Разница между Хр и Char при использовании в преобразовательных типов является то, что одна функция, а другой отливаютChar и Chr в Delphi

Итак: Char(66) = Chr(66)

Я не думаю, что есть какие-либо показатели разница (по крайней мере, я ее никогда не замечал, наверное, называет другую) .... Я уверен, что кто-то поправит меня по этому поводу!

EDIT Благодаря Ульриху за испытание, которое они на самом деле идентичны.
EDIT 2 Может ли кто-нибудь подумать о случае, когда они могут быть не идентичными, например. вас подталкивают к использованию одного над другим из-за контекста?

Что вы используете в своем коде и почему?

+0

Одна из ситуаций, в которых вы бы использовали Char вместо Chr, - это если вы делаете явное приведение, например, от AnsiChar. Спасибо Uwe Raabe –

+1

Это похоже на случай дублирования функций, возможно, по историческим причинам. Что-то вроде «исходной версии было вызвано Chr(), но тогда кто-то сказал, это будет иметь больше смысла, если мы назовем ее Char(), поскольку она в основном является типом для Char, но мы не можем ее изменить, потому что есть много существующий код, который использует Chr(), и это сломает его, поэтому мы просто поместим их обоих ». Это просто догадка, но это, вероятно, довольно близко к тому, что на самом деле произошло. –

+0

Оригинальный Паскаль от Дженсена/Вирта уже имел функцию Chr(), но никаких отливок типа. Они не вписывались в дизайн языка. –

ответ

5

Я сделал небольшой тест в 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 

Edit: Модифицированный образец для смягчения проблем Ника.

Редактировать 2: Желание Ника - моя команда. ;-)

+0

это похоже * обман *. Попытайтесь использовать переменную вместо константы. Если вы получите те же результаты, я отвечу на ваш ответ :) –

+0

+1, и если вы проверите 'ch: = chr (b); ch: = char (b); 'это будет идеально. –

0

Chr - вызов функции, это немного (крошечный крошечный) более дорогой, чем тип. Но я думаю, что Chr встроен компилятором.

2

chr - это функция, поэтому она возвращает новое значение типа char.

char(x) является литой, это означает, что используется фактический объект x, но как другой тип.

Многие системные функции, такие как inc, dec, chr, ord, являются встроенными.

И char, и chr Быстрые. Используйте тот, который наиболее подходит каждый раз,
и лучше отражает то, что вы хотите сделать.

+0

, если они оба идентичны ...(что они кажутся), то как вы можете сказать, какой из них подходит, более ли это случай «в зависимости от того, что вы чувствуете в то время»? –

+0

@JamesB, я не сказал, что они одинаковые. 'chr' - это функция. В большинстве случаев их можно рассматривать как * одинаковые *. –

+0

Chr не возвращает новое значение, оно возвращает результат выражения, заданного в качестве параметра. Выражение оценивается перед вызовом chr, а вызов chr абсолютно ничего не делает. –

3

помощь говорит: Chr возвращает символ с порядковым значением (значение ASCII) выражения байт типа, X. *

Итак, как символ представлен в памяти компьютера? Угадайте, что, как байт *. На самом деле функции Chr и Ord существуют только там, где Pascal является строго типизированным языком, запрещающим использование байтов *, где запрашиваются символы. Для компьютера результирующий символ по-прежнему представляется в виде байта * - для чего он будет тогда преобразован? На самом деле для этого вызова функции не существует кода, так же, как нет кода, опущенного для типа. Эрго: нет разницы.

Вы можете предпочесть chr, чтобы избежать литого типа.

Примечание: тип приведения не следует путать с явными преобразованиями типов! В Delphi 2010 написано что-то вроде Char(a), в то время как AnsiChar, на самом деле что-то сделает.

** Для Unicode замените байт с целыми *

Edit:

Просто пример, чтобы понять (предполагая, что не-Unicode):

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

производит подобный код

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().

+0

Функция ORD() работает только с символами. –

+0

Я знаю, что это был только пример. ORD() также возвращает только внутреннее целочисленное представление заданного порядкового типизированного значения. Таким образом, здесь нет никакой реальной функции вызова, и никакой код не испускается. –

0

Они идентичны, но они не имеют, чтобы быть идентичными. Нет требования, чтобы внутреннее представление символов отображало 1-к-1 с их порядковыми значениями. Ничто не говорит о том, что переменная Char, удерживающая значение 'A', должна удерживать числовое значение 65. Требование состоит в том, чтобы при вызове на эту переменную результат должен быть 65, потому что это кодовая точка, обозначенная буквой A в вашем кодировка символов программы.

Конечно, Простой Реализация этого требования также требует, чтобы переменная удерживала числовое значение 65. Из-за этого вызовы функций и типы-роли всегда одинаковы.

Если реализация была другой, тогда, когда вы вызвали Chr(65), компилятор будет искать, какой символ находится в точке 65 кода и использовать его в качестве результата. Когда вы пишете Char(65), компилятор не будет беспокоиться о том, какой символ он действительно представляет, пока числовой результат, сохраненный в памяти, равен 65.

Является ли это расщепляющимися волосками? Да, абсолютно, потому что во всех текущих реализациях они идентичны. Я уподобляю это тому, что нулевой указатель обязательно равен нулю. Это не так, но во всех реализациях все равно так или иначе.

0

chr is typeafe, char нет: попробуйте ввести код chr(256), и вы получите ошибку компилятора. Попробуйте ввести код char(256), и вы либо получите символ с порядковым значением 0 или 1, в зависимости от внутреннего представления ваших целых чисел на вашем компьютере.

Я буду суффикс выше, сказав, что это относится к предварительному Unicode Delphi. Я не знаю, были ли обновлены chr и char для учета unicode.

+0

Какие компьютеры используют внутреннее представление целых чисел, где титрование 256 на 'Char' даст символ с порядковым значением 255? –

+0

К сожалению, это научит меня публиковать, когда устал. Ответ исправлен. –

 Смежные вопросы

  • Нет связанных вопросов^_^