AnsiChar — Тип Delphi


Содержание

AnsiChar — Тип Delphi

Здравствуйте! подскажите пожалуйста как в
a: array[0..2000] of ansichar;
записать содержимое Memo (Delphi 2009). Заранее спасибо!

Почему именно в массив, а не в AnsiString ?

главное: зачем? не с со stream или файлами пытаешься работать?

Да ладно, нормальный вариант работы: один раз буфер выделил и работай с ним.


> smirnoff © (06.07.09 11:53)

> a: array[0..2000] of ansichar;
> записать содержимое Memo (Delphi 2009).

Memo.Perform(WM_GETTEXT, SizeOf(a), LParam(@a))

думаю мой вопрос не совсем для начинающих (а то его переместили).. в нем закопан подводный камень..

> Почему именно в массив, а не в AnsiString ?

потомучто с массивом придется работать. AnsiString не подходит уже пробовал. т.к. на массив ссылается b: pansichar;
b := @a;
а он в свою очередь передается как параметр для функции. (pansichar менять нельзя, всяко пробовал в d2009 глючить начинает. работает только с pansichar и функции нужен pansichar);


> главное: зачем? не с со stream или файлами пытаешься работать?

с файлами не работаю.

Увы
Memo1.Perform(WM_GETTEXT, SizeOf(a), LParam(@a))
не работает в delphi2009.


> работает только с pansichar и функции нужен pansichar

var
s : AnsiString;
begin
s := «Превед, Медвед!»;


> > работает только с pansichar и функции нужен pansichar var
> s : AnsiString;begin s := «Превед, Медвед!»; SomeFunction(PAnsiChar(s));
> end;

заработало! СПА-СИ-БО.
вот теперь это сношу:
a: array[0..2000] of ansichar;


> smirnoff © (06.07.09 15:18) [5]

> Увы
> Memo1.Perform(WM_GETTEXT, SizeOf(a), LParam(@a))
> не работает в delphi2009.

Не верю.


> Leonid Troyanovsky ©
> Не верю.

Memo1.Perform(WM_GETTEXT, SizeOf(a), LParam(@a));
ошибки нет. но в массиве «а» виден только первый символ из содержимого.
Delphi 12.0.3390.20513

var
a: array[0..2000] of ansichar;
begin
Memo1.Perform(WM_GETTEXT, SizeOf(a), LParam(@a));
ShowMessage(a);
end;
по ShowMessage видим только 1й символ из Memo.


> потомучто с массивом придется работать

А AnsiString, надо так понимать, для беззаботно отдыхающих и праздно дзенствующих ?


> думаю мой вопрос не совсем для начинающих

Судя даже по формулировке — там ему и место.

> думаю мой вопрос не совсем для начинающих (а то его переместили)..
Он не для начинающих. Он для даже еще не начавших. Извините, но это так.

> в нем закопан подводный камень..
И называется этот подводный камень — неумение работать со строками. Извините, но это тоже так.


> заработало! СПА-СИ-БО. вот теперь это сношу:

Уважаемые мастера. Имейте ввиду, что на поставленный вопрос никто не ответил правильно. был предложен альтернативный вариант отличный по функциональности.. он мне подошел. НО НА ВОПРОС НИКТО ТАК И НЕ ОТВЕТИЛ — продемонстрируйте же свои знания работы со строками, Юрий Зотов.

способы типа:

a: array[0..2000] of ansichar;
begin
for i := 1 to length(memo1.Lines.Text) do
a[i — 1] := ansichar(memo1.Lines.Text[i]);
или
a: array[0..2000] of ansichar;
begin
StrCopy(a,pansichar(Memo1.Text));

неуместны (для delphi 2009). почему? догадаетесь.


> подводный камень

— связан с кодировкой. русские символы теряются в указанных выше способах (только в d2009).


> — там ему и место

Да всё так. Спасибо, что все поставили на свои места. Еще только сайт остается назвать delphifighter.ru


> smirnoff © (06.07.09 19:44) [9]

> ошибки нет. но в массиве «а» виден только первый символ

Извини, но ты уже вышел из круга доверия.


> > ошибки нет. но в массиве «а» виден только первый символ
> Извини, но ты уже вышел из круга доверия.

понял что результат юникода.
ну да вообщето там есть всё остальное. НО с НАРУШЕННОЙ кодировкой. русские символы НЕ отображаются как надо.

Если [6] заработало (о чем Вы сказали в [7]), то никакого юникода у Вас на самом деле нет, а есть просто AnsiStrinng — то есть, массив однобайтовых символов. Далее:

1. Копирование одного массива в другой — задачка для детского сада. Но Вы на ней споткнулись.

2. Как выяснилось, копирование Вам понадобилось лишь для того, чтобы вызвать некую функцию с параметром PAnsiChar. Но для этого копировать вообще ничего не нужно — чего Вы тоже не знали.

3. В [9] Вы утверждаете, что «в массиве «а» виден только первый символ из содержимого». Это говорит о том, что Вы просто не умеете правильно интерпретировать содержимое памяти.

И после всего этого Вы говорите о каких-то подводных камнях и о том, что Ваш вопрос не для «начинающих»? Не смешите.

Кстати, [14] тоже подтверждает п.3 — Вы просто не умеете правильно интерпретировать содержимое памяти.

a: array[0..70] of ansichar; //массив, который необходимо заполнить.

«1», #0, «v», #20, #21, #1, #14, «Ђ», #152, «й», #1, #0, #0, #0, #0, #0, #0, #0, #0, #4,
#0, #0, #0, #0, #0, #0, #0, #1, #0, #0, #0, «l», «a», «t», «n», «§», » for i := 1 to length(memo1.Lines.Text) do
a[i — 1] := ansichar(memo1.Lines.Text[i]);
дает следующее:

Вот оно то, что нужно! Всем спасибо за участие, мастера! ;)
Маленький вопрос еще: у кого установлен d2009 (из тех, кто участвовал в дискуссии)?


> > > ошибки нет. но в массиве «а» виден только первый символ
> > Извини, но ты уже вышел из круга доверия.

Не обвиняйте меня жестокой топусти, я знаю что (напр.) ShowMessage и Memo будут отображать всё, пока не встретят 1-й ноль (не в кавычках — т.е. #0).

В чем разница между W >

Я обновляю некоторый древний (с 2003 года) код Delphi до Delphi Architect XE, и у меня возникают некоторые проблемы. Я получаю ряд ошибок, когда есть несовместимые типы. Эти ошибки не происходят в Delphi 6, поэтому я должен предположить, что это потому, что вещи были обновлены.

Честно говоря, я не знаю, в чем разница между PAnsiChar и PWideChar, но Delphi точно знает разницу и не даст мне скомпилировать. Если бы я знал, в чем заключаются различия, возможно, я мог бы выяснить, что использовать или как это исправить.

2 ответа

Коротко: до Delphi 2009 нативный тип строки в Delphi имел обыкновение быть ANSI CHAR: каждый символ в каждой строке был представлен как 8-битный символ. Начиная с Delphi 2009, строки Delphi стали UNICODE с использованием нотации UTF-16: теперь базовый Char использует 16 бит данных (2 байта), и вам, вероятно, не нужно много знать о кодовых точках Unicode, которые представлены в виде двух последовательные 16-битные символы.

8-битные символы называются «анси-символы». PAnsiChar — это указатель на 8-битные символы. 16-битные символы называются «широкими символами». PWideChar — это указатель на 16-битные символы. Delphi знает разницу и преуспевает, если не позволяет вам смешивать оба!

Больше информации

Вы можете найти более подробную информацию о переносе Delphi в Unicode здесь: Новая Белая книга: Миграция Delphi Unicode для простых смертных

Вы также можете найти SO для «Миграция Delphi Unicode».

Пару лет назад тип символов по умолчанию в Delphi был изменен с AnsiChar (однобайтовая переменная, представляющая символ ANSI) на WideChar (двухбайтовая переменная, представляющая символ UTF16.) Тип char теперь является псевдонимом WideChar вместо AnsiChar тип string теперь является псевдонимом UnicodeString (версия Unicode UTF-16 традиционного типа строки Delphi) вместо AnsiString , а тип PChar теперь является псевдонимом PWideChar вместо PAnsiChar .

Компилятор может сам позаботиться о многих преобразованиях, но есть несколько проблем:

  1. Если вы используете типы строковых указателей, такие как PChar , вам нужно убедиться, что указатель указывает на правильный тип данных, и компилятор не всегда может это проверить.
  2. Если вы передаете строки в параметры var , тип переменной должен быть точно таким же. Это может быть более сложным теперь, когда у вас есть два типа строк для работы.
  3. Если вы используете string как удобный буфер байтового массива для хранения произвольных данных вместо переменной, содержащей текст, это не будет работать как UnicodeString . Убедитесь, что они объявлены как RawByteString как обходной путь.
  4. Везде, где вы имеете дело с длиной строки в байтах, например, при чтении или записи в / из TStream, убедитесь, что ваш код не предполагает, что длина char составляет один байт.

Взгляните на Delphi Unicode Migration for Mere Mortals, чтобы узнать о некоторых хитростях и советах, как заставить это работать. Это не так сложно, как кажется, но и не тривиально. Удачи!

В чем разница между Ansichar и char?

Я недавно столкнулся с этим несоответствием типа данных. Этого я никогда не видел. Надеюсь, кто-то может объяснить, что это такое и как они отличаются.

Ошибка У меня был F2063. [Ошибка ДКК] E2010 Несовместимые типы: «AnsiChar» и «Чар»

Создан 20 окт. 14 2014-10-20 18:16:22 ThN

Вы попробовали Googling для сообщения об ошибке? Или нажатие F1 с сообщением об ошибке, выделенным в окне сообщений? Или попробуйте найти в документации для [AnsiChar] (http://docwiki.embarcadero.com/Libraries/XE7/en/System.AnsiChar) и [Char] (http://docwiki.embarcadero.com/Libraries/XE7/ ан/System.Char)? – Ken White 20 окт. 14 2014-10-20 18:25:42

рядом с: [Разница между PAnsiChar и PChar] (http: // stackoverflow.com/questions/1803426/difference-between-pansichar-and-pchar) – bummi 20 окт. 14 2014-10-20 18:29:00

Слишком плохо EMBA упустил явное различие между фундаментальными и родовыми типами . – Free Consulting 20 окт. 14 2014-10-20 19:18:13

Итак, если temp = 10, Char (10), то же самое, что Ansichar (температура)? – ThN 20 окт. 14 2014-10-20 19:33:27

@ThN нет. Они разные. Вы знаете что-нибудь о Unicode? – David Heffernan 20 окт. 14 2014-10-20 19:35:26

Каждый разработчик Delphi должен знать это, независимо от того, какую версию они используют. – Jerry Dodge 20 окт. 14 2014-10-20 19:50:23

Я не уверен, что это правильно, чтобы обозначить это как дубликат. Конкретный вопрос о конкретной ошибке компилятора — это другой вопрос, чем гораздо более широкий: «В чем разница между WideChar и ANSIChar?», Хотя ответ на последний связан с пониманием ответа на первое. Это как «Почему моя машина не начнет?» vs «В чем разница между углем и нефтью?» :)Deltics 20 окт. 14 2014-10-20 20:01:34

@Deltics Возможно, вы могли бы попросить по мета. Я думаю, что это так же ясно, как и может быть. Вы не согласны. Было бы полезно узнать, что думают мета-люди. – David Heffernan 20 окт. 14 2014-10-20 20:10:51

И так много обманывает этот вопрос. Попробуйте этот веб-поиск: * E2010 ansichar char сайт: stackoverflow.com * – David Heffernan 20 окт. 14 2014-10-20 20:16:31

@JerryDodge я делаю. Причина, по которой я даже разместил этот вопрос, состояла в том, что раньше я никогда не сталкивался с такой ошибкой. Я посылаю байт символа как CHAR через последовательный порт через переменную. В этой процедуре я использую и использую принятый тип параметра CHAR в Delphi 2007. Теперь я до 2010 года. Компилятор поднимает эти ошибки. Проблема в том, что я могу успешно отправить тип Char для литерального значения, например Char (13), но он терпит неудачу, когда (скажем, WORD temp = 13) передаю char (temp) и запрашивает, чтобы этот параметр должен быть типа Ansichar. Я делаю изменения, и программа успешно выполняется, но получение аппаратного обеспечения не выполняется. – ThN 20 окт. 14 2014-10-20 20:17:40

@ThN Что вы, похоже, не понимаете, так это то, что на D2007 ‘Char’ является псевдонимом для AnsiChar, который представляет собой один байт. И на D2010 ‘Char’ является псевдонимом для’ WideChar’, который представляет собой два байта. Пока вы не замедляетесь и не читаете ответы на этот и другие вопросы, прочитайте технический документ Марко и поистине понимаете огромную разницу между «AnsiChar» и «WideChar», что вы не достигнете прогресса. Вы не решите эту проблему, изменив ситуацию, пока компилятор не станет счастлив, и надеемся, что это может сработать. Вам нужно понять. – David Heffernan 20 окт. 14 2014-10-20 20:30:02

@ Давид — на самом деле не biggie, мне просто показалось, что вопросы на самом деле существенно различны, даже если ответы были очень похожи. : shrug: – Deltics 20 окт. 14 2014-10-20 23:33:14

http://stackoverflow.com/questions/6839019/delphi-2010-error-e2010- incompatible-types-ansichar-and-char . добавление для заполнения «связанной» боковой панели – J. 21 окт. 14 2014-10-21 09:10:09

В любом случае этот вопрос может быть закрыт или удален на этот момент времени? – ThN 23 окт. 14 2014-10-23 13:42:07

1 ответ

Исторически в Delphi, то Чар тип был фактически синонимом AnsiChar типа. То есть, один байт, представляющий символ из кодовой страницы ANSI. ПРИМЕЧАНИЕ:Это упрощение, которое игнорирует сложности, возникающие из многобайтовых символов, которые могут встречаться в строке ANSI, но этого достаточно для этого ответа.

Это соответствует с тем, что Строка тип был фактически синонимом AnsiString.

В Delphi 2009 г. это изменилось.

С Delphi 2009, Строка и типы Char стали синонимами для UnicodeStringWideString с дополнительными возможностями) и WideChar, соответственно, отражая переход к Unicode как родной формат для строки и типы символов. A WideChar — это 2-байтовое значение, представляющее один символ Юникода (или одну половину суррогатной пары).

Поэтому в версиях Delphi до Delphi 2009, следующие две переменные были совместимых типов:

Однако в Delphi 2009 и позднее значение «ч» деклараций изменений:

в результате ACH и ч переменных больше не совместимые типы.

то есть причина, вы получаете эту ошибку в том, что у вас есть код, который был объявлен с AnsiChar типов и другим кодом, который, используя значения, объявленные типа Чара. При компиляции с старой версией Delphi, где Char = AnsiChar, два набора кода совместим, но в Delphi 2009 и позже Char = WideChar и поэтому оба типа (Char и AnsiChar) является не совместимый.

Создан 20 окт. 14 2014-10-20 19:20:56 Deltics

Илон Маск рекомендует:  Событие сохранения документа (IE)

AnsiChar — Тип Delphi

В этой статье рассказывается о том, что Вам нужно сделать, чтобы подготовить свой код к Delphi 2009.

В Части I этой серии было сказано, что Delphi 2009 по умолчанию будет использовать строку, основанную на UTF-16. В результате некоторые части существующего кода могут потребовать изменений. В основном, большая часть существующего кода будет прекрасно работать в Delphi 2009. Как Вы увидите, основные изменения в коде касаются только очень специфических, даже эзотерических, моментов. Как бы там ни было, нужно рассмотреть те особые части кода, которые, скорее всего, придется редактировать. Также нужно будет проверить результаты работы такого кода, чтобы убедиться, что он правильно работает с UnicodeString.

Например, любой код, работающий со строками и выполняющий операции с указателями на них, должен быть изучен на совместимость с Юникодом. Говоря более конкретно, любой код:

  • считающий, что SizeOf(Char)=1;
  • считающий, что длина строки равна количеству байт в строке;
  • который пишет и читает строки из какого-либо постоянного хранилища или использует строку как буфер для данных

должен быть проанализирован, чтобы убедиться, что эти особенности не влияют на работу. Код, который пишет и читает из какого-либо постоянного хранилища, должен быть проверен на то, что считывается или пишется правильное количество байт, так как один байт больше не является одним символом.

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

Части, которые должны «работать прямо так»

Здесь рассказывается о тех частях кода, которые будут продолжать работать и не потребуют никаких изменений для корректной работы с новой UnicodeString. VCL и RTL были полностью обновлены, чтобы работать в Delphi 2009 так, как и всегда. С маленькими-маленькими оговорками так оно и есть. К примеру, TStringList теперь полностью поддерживает Юникод, и весь существующий код, в котором используется TStringList, должен работать так же, как и раньше. Кроме того, TStringList был улучшен для работы специально с Юникодом, поэтому если Вы хотите использовать новую функциональность, Вы можете это сделать, но если это Вам не нужно — можете вообще о ней не думать.

Обычное использование строковых типов

В основном, код, использующий строковый тип, будет работать, как и прежде. Нет необходимости переобъявлять строковые переменные в тип AnsiString, за исключением тех случаев, которые описаны ниже. Объявления строк должны быть изменены на AnsiString во всех местах, где строки используются в качестве буфера для данных.

Runtime Library

Дополнения к Runtime Library были подробно рассмотрены в Части II.

В той статье не упоминался новый модуль, добавленный в RTL — AnsiString.pas. Этот модуль существует для обратной совместимости с кодом, который использует или требует для своей работы AnsiString.

Код Runtime Library выполняется как обычно, и в основном не требует изменений. Части, которые нужно изменить, описаны ниже.

Вся VCL поддерживает Юникод. Все существующие VCL-компоненты работают с момента установки, как всегда и было. Практически весь код, использующий VCL, будет нормально работать. Мы проделали огромную работу, чтобы быть уверенными, что VCL совместим как со старым кодом, так и с Юникодом. Обычный VCL-код, не выполняющий никаких особенных манипуляций со строками, будет работать как и раньше.

Индексация в строках

Индексация в строках работает точно так же, как и прежде, поэтому код, индексирующий элементы строк, не требует изменений:

Length/Copy/Delete/SizeOf для строк

Функция Copy будет работать, как всегда, без изменений. То же самое относится к Delete и всем остальным процедурам работы со строками, основанными на SysUtils.

Вызов Length(SomeString), как и всегда, вернет количество элементов в переданной строке.

Вызов SizeOf для любого идентификатора строки вернет 4, так как все строковые объявления — это ссылки и размер указателя равен 4.

Вызов Length для любой строки вернет количество элементов в этой строке.

Рассмотрим следующий код:

В результате его выполнения будет выведено следующее:

Работа с указателями для PChar

Работа с указателями для PChar будет выполняться, как и раньше. Компилятору известен размер PChar, поэтому код, подобный приведенному ниже, будет работать, как и ожидается:

Этот код будет работать точно так же, как и в предыдущих версиях Delphi, но, конечно, с другими типами данных: PChar это теперь PWideChar и MyString — это теперь UnicodeString.

ShortString

ShortString осталась неизменной, как по функциям, так и по объявлению, она будет работать, как и раньше.

Объявления ShortString выделяют буфер для заданного количества AnsiChar»ов. Такой код:

выведет на экран следующее:

Обратите внимание, что общий размер алфавита — 26, это говорит о том, что переменная содержит AnsiChar»ы.

Рассмотрим также и такой код:

Это запись будет расположена в памяти точно так же, так и раньше — это будет запись из двух AnsiString»ов, содержащих AnsiChar»ы. Если у Вас есть File of Rec из записей, содержащих ShortString»и, то приведенный выше код будет работать, как и раньше, и любое чтение или запись не потребует никаких изменений.

Однако помните, что Char — это теперь WideChar, поэтому если Вы используете код, который читает такие записи из файла и потом делаете что-то вроде:

то Вы должны помнить, что SomeChar превратит AnsiChar в String1[3] в WideChar. Если Вам нужно, чтобы этот код работал, как раньше, измените объявление SomeChar:

Части, которые должны быть проверены

В этой части статьи описаны различные конструкции, которые должны быть проверены в существующем коде для совместимости с Юникодом. Поскольку Char теперь является WideChar, данные о байтовом размере символьного массива или строки могут быть неверными. Ниже приведены несколько примеров конструкций кода, которые нужно изучить, чтобы убедиться в их совместимости с новым типом UnicodeString.

SaveToFile/LoadFromFile

Вызовы SaveToFile и LoadFromFile можно было бы отнести к предыдущей части статьи (Части, которые должны «работать прямо так»), если бы они выполняли чтение и запись так же, как они делали это раньше. Однако Вам может понадобиться использование новых перегруженных версий этих процедур, если Вы решили работать с Юникод-данными.

К примеру, TStrings теперь включает следующий набор перегруженных методов:

Второй метод — это новая перегрузка, принимающая кодировку в качестве параметра, который задает, каким образом данные будут записаны в файл. (В Части II Вы можете прочитать описание типа TEncoding.) Если Вы вызовете первый метод, строковые данные будут записаны так же, как это делалось обычно — как ANSI-данные. Благодаря этому уже существующий код будет работать точно так же, как и всегда.

Однако если Вам нужно записать текст в формате Юникод, то нужно вызвать второй вариант метода, передав ему в параметре соответствующее значение типа TEncoding. Если не сделать этого, строки будут записаны как ANSI-данные, что, скорее всего, приведет к потере информации.

Таким образом, наилучший способ в этом случае — проанализировать вызовы SaveToFile и LoadFromFile и добавить к ним второй параметр, чтобы показать, каким образом нужно сохранить или загрузить данные. Если Вы считаете, что никогда не будете добавлять или использовать Юникод-строки, то можете оставить все, как есть.

Использование функции Chr

Существующий код, превращающий значение типа integer в Char может использовать функцию Chr. Это может привести к следующей ошибке:

Если в коде, использующем функцию Chr, имеется присвоение ее результата переменной типа AnsiChar, то эту ошибку можно легко исключить, заменив функцию Chr преобразованием в тип AnsiChar.

То есть, такой код:

можно заменить таким:

Символьные множества

Наверное, самой распространенной идиомой, которая может создать проблемы компилятору, является использование символов в множествах. Раньше, когда символ занимал один байт, хранение символов в множествах не создавало никаких трудностей. Но теперь Char объявлен как WideChar, и поэтому больше не может храниться в множестве. Поэтому, если у Вас есть код наподобие этого:

и Вы скомпилируете его, то получите предупреждение, которое будет выглядеть примерно так:

Если хотите, можете оставить код неименным — компилятор будет «знать», что Вы пытаетесь сделать и сгенерирует правильный код. Однако, если Вы хотите избавиться от этого предупреждения, то можете использовать новую функцию CharInSet:

Функция CharInSet вернет булевское значение и код скомпилируется без предупреждений компилятора.

Использование строк в качестве буферов данных

Часто при работе с данными строки используются как буферы. Это делается часто, потому что это просто — работа со строками проста и понятна. Однако, существующий код, который так делает, в большинстве случаев потребует дополнительной настройки, исходя из того, что string это теперь UnicodeString.

Есть несколько способов разобраться с кодом, который использует строки как буферы данных. Первый — это просто объявить переменную, используемую в качестве буфера, как AnsiString вместо string. Если для работы с байтами буфера в коде используются Char»ы — объявите эти переменные как AnsiChar. Если Вы выберете этот путь, весь Ваш код будет работать, как и прежде, но Вы должны помнить: все переменные, работающие с таким строковым буфером, должны быть ANSI-типа.

Второй, более верный путь, — это преобразовать Ваш буфер из строкового типа в массив байтов или TBytes. Тип TBytes был создан специально для этой цели и работает так же, как и раньше, если использовался тип string.

Вызов SizeOf для буферов

Вызов SizeOf при использовании символьных массивов должен быть проверен на корректность. Рассмотрим следующий код:

Вот что этот код выведет в Memo1:

В этом коде Length вернет количество символов в данной строке (плюс терминальный символ), а SizeOf вернет количество байтов, использованных этим массивом, в данном случае 34, то есть по два байта на символ. В предыдущих версиях Delphi этот код вернул бы 17 в обоих случаях.

Использование FillChar

Вызов FillChar также нужно проверить при работе со строками и символами. Рассмотрим следующий код:

Length возвращает размер в символах, но FillChar ожидает, что Count будет в байтах. В этом случае вместо Length нужно использовать SizeOf (или нужно умножить Length на размер Char).

Кроме того, так как по умолчанию размер Char равен 2, FillChar заполнит строку байтами, а не символами, как раньше.

Это заполнит массив символами с кодом не $09, а $0909. Чтобы получить прежний результат, код нужно изменить:

Использование буквенных символов

распознает символ Евро и в итоге даст True в большинстве кодовых страниц ANSI. Однако в Delphi 2009 он даст False, так как #128 — это символ Евро в большинстве ANSI-страниц, а в Юникоде это — управляющий символ. В Юникоде символом Евро имеет код #$20AC.

При переходе на Delphi 2009 разработчикам следует заменить все коды символов со #128 по #255 на их буквенные значения, тогда:

будет работать так же, как #128 в ANSI, но будет нормально функционировать (то есть распознавать символ Евро) в Delphi 2009 (где ‘€’ имеет код #$20AC)

Использование Move

Следует проанализировать использование функции Move при работе со строками или символьными массивами. Рассмотрим следующий код:

Length возвращает размер в символах, но Move ожидает, что Count будет в байтах. В этом случае вместо Length нужно использовать SizeOf (или нужно умножить Length на размер Char).

Методы Read/ReadBuffer для TStream

Вызов TStream.Read/ReadBuffer также следует рассмотреть, если используются строки или символьные массивы. Рассмотрим следующий код:

Примечание: работа зависит от формата читаемых данных. Смотрите описание нового класса TEncoding, приведенное выше, для получения сведений о правильном кодировании текста в Stream»е.

Write/WriteBuffer

Как и в случае Read/ReadBuffer, использование TStream.Write/WriteBuffer следует проверить, если используются строки или символьные массивы. Рассмотрим следующий код:

Примечание: работа зависит от формата читаемых данных. Смотрите описание нового класса TEncoding, приведенное выше, для получения сведений о правильном кодировании текста в Stream»е.

LeadBytes

Замените такой код:

использованием функции IsLeadChar:

TMemoryStream

В тех случаях, когда для записи текста в файл используется TMemoryStream, важной является запись Byte Order Mark (BOM) в качестве начальных данных файла. Вот пример записи BOM в файл:

TStringStream

TStringStream теперь происходит от нового типа TByteStream. TByteStream добавляет свойство Bytes, дающее прямой доступ к байтам из TStringStream. TStringStream продолжает работать, как и всегда, за исключением того, что строка, которую он хранит, теперь является Юникод-строкой.

MultiByteToWideChar

Вызовы MultiByteToWideChar можно просто убрать и заменить простым присвоением. Пример использования MultiByteToWideChar:

А после перехода к Юникоду этот код был изменен, чтобы компилироваться как для ANSI, так и для Юникода:

SysUtils.AppendStr

Этот метод может использовать только AnsiString, нет его перегруженной версии для UnicodeString.

Замените вызовы вроде этого:

Или, еще лучше, используйте новый класс TStringBuilder для соединения строк.

GetProcAddress

При вызове GetProcAddress всегда следует использовать PAnsiChar (в SDK нет функции с суффиксом «W»). Например:

Примечание: Windows.pas содержит перегруженный метод, который выполняет это преобразование.

Использование преобразований к PChar() для работы с указателями при указании на не символьные типы

В предыдущих версиях не все типизированные указатели поддерживали арифметические операции. Из-за этого для выполнения арифметических операций над такими указателями они преобразовывались к PChar. В Delphi 2009 арифметика для указателей может быть включена директивой компилятора и она специально включена для типа PByte. Таким образом, если у Вас есть подобный код, преобразующий указатель к PChar для выполнения арифметических операций над ним:

В приведенном выше куске кода Node не содержит символьных данных. Он преобразовывается к PChar только для доступа к данным, расположенным через заданное число байт после Node. Раньше это работало, так как SizeOf(Char) = SizeOf(Byte). Теперь это работать не будет. Чтобы сделать работу кода правильной, следует использовать PByte вместо PChar. Если оставить все без изменений, Result будет указывать на некорректные данные.

Параметры с вариантными массивами

Если Ваш код использует TVarRec для работы с параметром — вариантным массивом — возможно, Вам придется отредактировать его для работы с UnicodeString. Для этого теперь есть новый тип vtUnicodeString, хранящий данные из UnicodeString. Рассмотрим следующий кусок из DesignIntf.pas, показывающий, в каком случае следует добавить новый код для работы с UnicodeString.

CreateProcessW

Юникод-версия CreateProcess (CreateProcessW) работает немного иначе, нежели ANSI-версия. Цитата MSDN из описания параметра lpCommandLine:

«Юникод-версия это функции, CreateProcessW, может изменить содержимое этой строки. Таким образом, этот параметр не может указывать на память только-для-чтения (то есть быть константной переменной или символьной строкой). Если этой параметр — константа, функция может вызвать ошибку доступа.»

Из-за этого существующий код, вызывающий CreateProcess, может начать выдавать ошибки доступа (Access Violations) после компиляции в Delphi 2009.

Примеры такого кода:

Передача строковой константы


Передача константного выражения


Передача строки с числом ссылок (Reference Count) -1:


Код для проверки

Вот список возможных мест в коде, которые Вам следует найти, чтобы проверить, готов ли Ваш код к правильному использованию Юникода:

  • найти любое использование «of Char» или «of AnsiChar», чтобы проверить, что буферы корректно работают с Юникодом;
  • найти «string[» и проверить, что символ, полученный по ссылке, заносится в Char (то есть в WideChar).
  • проверить неявную работу с AnsiString, AnsiChar и PAnsiChar, убедиться, что она по-прежнему нужна и правильно работает;
  • найти неявное использование ShortString, убедиться, что оно по-прежнему требуется и правильно работает;
  • найти вызовы Length( и проверить, чтобы там не подразумевалось, что Length это то же самое, что SizeOf;
  • найти вызовы Copy(, Seek(, Pointer(, AllocMem( и GetMem( и проверить, чтобы они правильно работали со строками или символьными массивами.
Илон Маск рекомендует:  Форматирование кода CSS

Это типичные конструкции, которые, возможно, придется изменить для поддержки нового типа UnicodeString.

Заключение

Вот и все потенциально узкие места в коде, которые нужно проверить на правильность для жизни в мире Юникода. Большая часть Вашего кода по-прежнему будет работоспособной. Большинство предупреждений, которые получит Ваш код от компилятора, можно легко исправить. Значительная часть моментов, которые нужно проверить, встречается достаточно редко, поэтому практически весь Ваш код будет работать просто прекрасно.

Классификация типов данных в Delphi. Типы с плавающей точкой (Double, Single, Real, Extended)

Типы бывают: 1)Простые/Порядковые (целый, логический, символьный, перечисляемый, диапазон (интервальный тип)); 2)Вещественный; 3)Структурированные(массивы, записи, файлы, классы, интерфейсы); 4)Строки; 5)Указатели; 6)Вариант; 7)Процедурный тип.

Типы с плавающей точкой:

Тип Размер(byte) Кол-во значащих цифр Диапазон
Single 7-8 1.5e-45 … 3.4e38
Double 15-16 5.0e-324 . 1.7e308
Real 11-12 2.9e-39 … 1.7e38
Extended 19-20 3.4e-4951 … 1.1e4932

S-e-m

Здесь m – знаковый разряд числа; e – экспоненциальная часть (содержит двоичный порядок); m – мантисса числа.

Мантисса m имеет длину от 23 (для Single) до 63 (для Extended) двоичных разрядов, что и обеспечивает точность 7-8 для Single и 19-20 для Extended десятичных цифр. Десятичная точка(запятая) подразумевается перед левым (старшим) разрядом мантиссы, но при действиях с числом она сдвигается влево и вправо в соответствии с двоичным порядком числа, хранящимся в экспоненциальной части, поэтому действия над вещественными числами называют арифметикой с плавающей точкой(запятой).
Особые операции :
Round( r ) – 3 округление (r= 2.6);
Trunc ( 2.8 ) – 2 целая часть;
Int (2.8 ) – 2.0 округление дробной части;
Frac (2.8) – 0.7 дробная часть.
11. Порядковые типы. Целые типы в Delphi, тип диапазон

К порядковым типам относятся целые типы, логический и символьный типы, а так же перечисления и тип-диапазон(пользовательский тип). К любому из них применима функция ORD(X) , которая возвращает порядковый номер значения выражения X. Для целых типов ORD(X) возвращает само значение X. Применение к логическому, символьному и к перечислениям дает «+» целое число в диапазоне 0-1(лог. тип), 0-255 (символьный), 0-65535 (перечисление). У типа-диапазон результат применения ord(x) зависит от свойств базового порядкового типа.
Так же к порядковым типам можно применять функции:
PRED(X) – возвращает предыдущее значение порядкового типа ( ord(pred(x)) = ord(x)-1).

SUCC(X)– возвращает следующее значение порядкового типа( ord(succ(x)) = ord(x)+1).
Вот некоторые целые типы :

Название типа Размер в байтах Диапазон
Byte 0…255
Shortint -128…127
Word 0…65535
Integer -2147483647…2147483295

К типам применимы следующие функции :

Abs(x)–возвращает модуль X

Chr(x)–возвращает символ по его коду

Dec(x)–уменьшает значение на 1

Inc(x)–увеличивает значение на 1
Div–целочисленное деление

Mod–дробная часть деления

Sqr(x)–возвращает квадрат X

А так же операции *,/,+,.
При работе с данными, нужно следить за тем, чтобы они не выходили за границы диапазона значений.
Тип-диапазон – это подмножество своего базового типа, в качестве которого может выступать любой порядковый тип, кроме типа-диапазона. Задается границами своих значений внутри базового типа : .. .Есть две функции : HIGH(x) — возвращает максимальное значение типа-диапазона, к которому принадлежит переменная Х.
LOW(x) — возвращает минимальное значение типа-диапазона.

12.Порядковые типы. Символьный тип. Таблица символов.
Значениями символьного типа является множество символов компьютера. Каждому символу присваивается целое число в диапазоне от 0 до 255. Это число служит кодом внутреннего представления символа, его возвращает функция ORD. В Delphi 7 есть три символьных типа :

Тип ANSIChar представляет собой так называемые Ansi-символы. Это символы, которые используются в операционных системах семейства Windows(размером 1 байт). Тип WideChar предназначен для хранения так называемых Unicode-символов, которые в отличие от Ansi-симвояов занимают два байта. Это позволяет кодировать символы числами от 0 до 65535 и используется для представления различных азиатских алфавитов. Первые 256 символов в стандарте Unicode совпадают с символами Аnsi.Тип Char в Delphi 7 эквивалентен типу AnsiChar и обеспечивает наибольшую производительность. Для отображения множества символов в подмножество натуральных чисел и обратно имеются следующие две стандартные функции:

ord(c) — дает порядковый номер символа с;
chr(i) — дает символ с порядковым номером i.
UpCase(CH) – возвращает прописную букву, если CH– строчная латинская буква, в противном случае возвращает сам символ.
Length( ) – функция, результатом которой является длина указанной строки.
13.Логический тип. Логические операторы и операции сравнения.
Значениями логического типа может быть одна из предварительно объявленных констант False или True.
Ord (False) =0; Ord (True) = 1; False

14.Порядковые типы. Перечисляемый тип.(пользовательский тип)
Перечисление, или перечисляемый тип
, задается перечислением тех значений, которые он может получать. Каждое значение именуется некоторым идентификатором и располагается в списке, обрамленном круглыми скобками, например :
Type
TSound = (‘ click, clack, clock’);

Описание переменных : var snd:TSound;
Особые операции:
ord(snd) – возвращает номер значения по порядку начиная с нуля(нумерацию можно начинать с единицы, если в типе указать : Type TSound = (‘click’=1,’ clack, clock’).

15.Тип массив(статический) : описание, ввод, вывод. Форматный вывод.
Это пользовательский тип.
Отличительная особенность массивов заключается в том, что все их компоненты – суть данные одного типа. Эти компоненты можно легко упорядочить и обеспечить доступ к любому из них простым указанием его порядкового номера.
Описание типа массива : = array [ ] of ;
– правильный идентификатор; array,of – зарезервированные слова(массив, из); – список из одного или нескольких индексных типов, разделенных запятыми; – любой тип Паскаля.
В качестве индексных типов в Паскале можно использовать любые порядковые типы, кроме LongInt и типов-диапазонов с базовым типом LongInt.
Обычно в качестве индексного типа используется тип-диапазон, в котором задаются границы индексов. Так как тип за словом of,– это любой тип Паскаля, он может быть, в частности, и другим массивом, например :
type mat = array [0..5,-1..2,Char] of Byte.

Ввод и вывод begin a.b : =100; writeln(a.b); End.

16.Тип запись : описание, ввод, вывод, Оператор With. Запись с вариантами.
Запись
– это структура данных, состоящая из фиксированного количества компонентов, называемых полями записи. В отличие от массива компоненты (поля) записи могут быть различного типа. Чтобы можно было ссылаться на тот или иной компонент записи, поля именуются.
Структура объявления типа записи такова :
= record end;
– правильный идентификатор ;record,end – зарезервированные слова(запись, конец); – список полей, представляющий собой последовательность разделов записи, между которыми ставится точка с запятой. Каждый раздел записи состоит из одного или нескольких идентификаторов полей, отделяемых друг от друга запятыми. За идентификатором(-ми) ставится двоеточие и описание типа поля(-ей).
Описание : type BirthDay = record
day, month : Byte;
year : Word end;
var a, b: BirthDay;

К каждому из компонентов записи можно получить доступ, если использовать составное имя, то есть указать имя переменной, затем точку и имя поля : a. Day : = 27
Для вложенных полей приходится продолжать уточнения :
Type BirthDay = record …. End;
var c : record
name : String ;
bd : BirthDay ;
end;
begin
…. If c. bd. Year = 1939 then
end.
Чтобы упростить доступ к полям записи, используется оператор присоединения WITH :
with do
with, do – ключевые слова ( с, делать) ; – имя переменной типа запись, за которой, возможно, следует список вложенных полей; – любой оператор Паскаля.
Например : with c. bd do month : = 9;
В Паскале допускается использовать записи с так называемыми вариантными полями, например :
Type Forma = record
Name :String ;
case Byteof
0 : (BirthPlace : String [40] ) ;
1 : ( Country : String [20] ) ;
end;
17.Тип множество : описание, ввод, вывод, операции над множествами.
Множество
– это наборы однотипных, логически связанных друг с другом объектов. Характер связей между объектами лишь подразумевается программистом и никак не контролируется в Паскалем. Количество элементов, входящих в множество, может меняться в пределах от 0 до 256. Именно непостоянством количества своих элементов множества отличаются от массивов и записей.
Два множества эквивалентны ó все их элементы одинаковые, причем порядок следования может быть разным. Если одни элементы одного множества входят также и в другое, то говорят о включении первого множества во второе.
Пример определения и задания множеств :
type
digitChat = set of ‘0’ .. ‘9’ ;
var s1,s2,s3: digitChar;

Ввод и вывод : S1:=[ 1..10]; … Writeln(s1); End.

S2:=[‘2’,’3’,’1’];
s3:=[‘2’,’3’];

end.
В этом примере s1 и s2 эквивалентны, а s3 включено в s2, но не эквивалентно ему.
Описание :
= set of
– правильный идентификатор;set, of – зарезервированные слова (множество, из); – базовый тип элементов множества, в качестве которого может использоваться любой порядковый тип, кроме Word, Integer, LongInt.
Над множествами определены следующие операции :
а) пересечение множеств (*) – результат содержит элементы, общие для обоих множеств.
б) объединение множеств (+) – результат содержит элементы первого множества, дополненные элементами из второго множества.
в) разность множеств (-) – результат содержит элементы первого множества, которые не принадлежат второму.
г) проверка эквивалентности (=) – возвращает True, если оба множества эквивалентны.
д) проверка неэквивалентности (<>) – возвращает True, если оба множества неэквивалентны.
е) проверка вхождения первого множества во второе ( =) – возвращает True, если второе множество включено в первое.
з)проверка принадлежности (in) – в этой бинарной операции первый элемент – выражение, а второй – множество одного и того же типа; возвращает True если выражение имеет значение, принадлежащее множеству, (см. предыдущий пример) 1 in s1 возвращает True, а 2*2 in s2 возвращает False.
и) Include – включает новый элемент в множество ( Include (S, I), здесь S- множество, I – элемент)
Exclude – исключает элемент из множества ( Exclude (S, I)).

18.Текстовый файл : описание файловой переменной, основные операции. Использование параметров программы для передачи программе имен файлов.
Текстовый файл – совокупность строк (последовательностей символов) переменной длины, заканчивающихся специальным символом eoln (конец строки; на клавиатуре набирается нажатием клавиши Enter).
Описание файловой переменной : : TextFile; или просто Text.
Первоначально любой файл данных создается как текстовый. Набранные на клавиатуре данные представляют собой стандартный входной файл. Содержимое дисплея при просмотре любого файла – стандартный выходной файл. Эти файлы используются при задании и просмотре данных. Для хранения данных последние записываются в файл на внешнем запоминающем устройстве (диске).

Основные операторы для работы с текстовыми файлами:
assignFile( ,’ ’) – связывает файловую переменную с файлом;
rewrite( ) – создание и открытие нового файла для записи;
reset ( ) – открытие существующего текстового файла (файла, связанного с файловой переменной ) для чтения;
append( ) – открытие существующего текстового файла (файла, связанного с файловой переменной ) для дозаписи в конец;
closeFile( ) – закрытие открытого файла.

Операторы ввода-вывода:
read( , ) – чтение данных; элемент списка ввода для текстового файла – число или символ или строка string;
write( , ) — запись данных согласно списку вывода; элемент списка вывода для текстового файла – число или символ или строка string.
readln( , ) — чтение данных согласно списку ввода и переход на следующую строку; если в строке данных остались данные, не вошедшие в список ввода, они игнорируются
writeln( , ) — запись данных в файл согласно списку вывода с добавлением в конце выведенной строки маркера конца строки (переход на следующую строку).
Параметры :
assignFile(dat, ParamStr(1));
assignFile(res, ParamStr(2));
ParamStr – стандартная функция для работы с параметрами в Delphi, она возвращает параметр с заданным номером. Ее синтаксис:
function ParamStr( : word): string;

Все параметры трактуются как отдельные строки (string). Параметры пользователя нумеруются, начиная с единицы. В нулевом параметре ParamStr(0) ОС передает программе полное имя запускаемого приложения (например, D:\Гречкина\Project1.exe). Этот (нулевой) параметр не входит в общее число параметров, которое можно узнать с помощью функции ParamCount: function ParamCount: word.
19.Назначение и отличие процедур общего вида и функций.
Назначение
. Подпрограммы (процедуры и функции) представляет собой инструмент, с помощью которого любая программа может быть разбита на ряд в известной степени независимых друг от друга частей. Такое разбиение необходимо по двум причинам :
1)Средство экономии памяти.
2)Применение методики нисходящего проектирования, благодаря которой достигаются достаточно простые алгоритмы, которые можно легко запрограммировать.
Отличие : Процедуры и функции представляют собой относительно самостоятельные фрагменты программы, оформленные особым образом и снабженные именем. Отличие процедуры от функции заключается в том, что результатом исполнения операторов, образующие тело функции, всегда является некоторое единственное значение или указатель, поэтому вызов функции, поэтому вызов функции можно использовать в соответствующих выражениях наряду с переменными и константами.
20. Описание и вызов процедур.
Формат описания процедуры имеет вид:

procedure имя процедуры (формальные параметры);

раздел описаний процедурыbegin исполняемая часть процедурыend;
Вызов:
имя процедуры (формальные параметры);


21. Описание и вызов функций.
Формат описания функции:

function имя функции (формальные параметры):тип результата;

раздел описаний функции

begin
исполняемая часть функции
end;Вызов:
Имя переменной:=имя функции (формальные параметры);…
ИЛИ
имя процедуры (имя функции (формальные параметры));
22. Классы формальных параметров: параметры-константы, параметры-значения, параметры-переменные. Ключевые слова const, var, out при описании параметров.Параметры-значения

Формальный параметр-значение обрабатывается, как локальная по отношению к процедуре или функции переменная, за исключением того, что он получает свое начальное значение из соответствующего фактического параметра при активизации процедуры или функции. Изменения, которые претерпевает формальный параметр-значение, не влияют на значение фактического параметра.
Соответствующее фактическое значение параметра-значения должно быть выражением и его значение не должно иметь файловый тип или какой-либо структурный тип, содержащий в себе файловый тип.
Фактический параметр должен иметь тип, совместимый по присваиванию с типом формального параметра-значения. Если параметр имеет строковый тип, то формальный параметр будет иметь атрибут размера, равный 255.
Параметры-константы
Формальные параметры-константы работают аналогично локальной переменной, доступной только по чтению, которая получает свое значение при активизации процедуры или функции от соответствующего фактического параметра. Присваивания формальному параметру-константе не допускаются. Формальный параметр-константа также не может передаваться в качестве фактического параметра другой процедуре или функции.
Параметр-константа, соответствующий фактическому параметру в операторе процедуры или функции, должен подчиняться тем же правилам, что и фактическое значение параметра.
В тех случаях, когда формальный параметр не изменяет при выполнении процедуры или функции своего значения, вместо параметра-значения следует использовать параметр-константу. Параметры-константы позволяют при реализации процедуры или функции защититься от случайных присваиваний формальному параметру. Кроме того, для параметров структурного и строкового типа компилятор при использовании вместо параметров-значений параметров-констант может генерировать более эффективный код.
Параметры-переменные
Параметр-переменная используется, когда значение должно передаваться из процедуры или функции вызывающей программе. Соответствующий фактический параметр в операторе вызова процедуры или функции должен быть ссылкой на переменную. При активизации процедуры или функции формальный параметр-переменная замещается фактической переменной, любые изменения в значении формального параметра-переменной отражаются на фактическом параметре.
Внутри процедуры или функции любая ссылка на формальный параметр-переменную приводит к доступу к самому фактическому параметру. Тип фактического параметра должен совпадать с типом формального параметра-переменной (вы можете обойти это ограничение с помощью нетипизированного параметра-переменной).
Примечание: Файловый тип может передаваться только, как параметр-переменная.
23. Массивы и записи как формальные параметры процедур и функций.
Объявление :
Type mas = array [1..100] of integer;
procedure massiv ( a : mas);

Открытый массив представляет собой формальный параметр подпрограммы, описывающий базовый тип элементов массива, но не определяющий его размерности и границы
procedure MyProc( OpenArray : array of Integer);
Внутри такой параметр трактуется как одномерный массив с нулевой нижней границей. Верхняя граница открытого массива возвращается функцией High.Используя 0 как минимальный индекс, подпрограмма может обрабатывать одномерные массивы произвольной длины.
24. Имена процедур и функций как фактические параметры процедур( Процедурный тип).
Процедурные типы — это нововведение фирмы Borland (в стандартном Паскале таких типов нет). Основное назначение этих типов — дать программисту гибкие средства передачи функций и процедур в качестве фактических параметров обращения к другим процедурам и функциям.
Для объявления процедурного типа используется заголовок процедур, в котором опускается ее имя, например:
type
Proc = procedure (a, b, с : Real; Var d : Real);
Proc2 = procedure (var a, b);
РгосЗ = procedure;
Func1 = function : String;
Func2 = function ( var s : String) : Real;
В программе могут быть объявлены переменные процедурных типов, например,так:
var
р1 : Proc;
ар : array [1..N] of Proc1;
Переменным процедурных типов допускается присваивать в качестве значений имена соответствующих подпрограмм. После такого присваивания имя переменной становится синонимом имени подпрограмм.
В отличие от стандартного Паскаля, в Турбо Паскале разрешается использовать в передаваемой процедуре как параметры-значения, так и параметры-переменные
<ознакомиться с файлом ProcType на сайте Гречкиной>
25.Модули в Паскале : назначение, описание, использование. Обязательные и дополнительные разделы.
Модуль
– это автономно контролируемая программная единица, включающая в себя различные компоненты раздела описаний ( типы, константы, переменные, процедуры и функции) и, возможно, некоторые исполняемые операторы инициализирующей части.
Структура модуля :
unit ;
interface

Илон Маск рекомендует:  Что такое код asp getpreviousdescription

implementation

begin

end.
Если в модуле используются другие модули, то нужно объявить их словом uses,оно можется следовать сразу за словом interface, либо сразу за словом implementation, либо и там и там.
unit – зарезервированное слово( единица); interface – зарезервированное слово (интерфейс), начинающее интерфейсную часть модуля; implementation – зарезервированное слово(выполнение), начинающее исполняемую часть модуля; begin – зарезервированное слово, начинающее инициализирующую часть модуля(эта конструкция begin необязательна); end – зарезервированное слово, являющееся признаком конца модуля.
В части interface содержатся объявления всех глобальных объектов модуля, которые должны стать доступными основной программе и(или) другим модулям.
В части implementation содержит описания подпрограмм, объявленных в интерфейсной части. В ней могут объявляться локальные для модуля объекты – вспомогательные типы, константы, переменные и блоки, а так же метки, если они используются в инициализирующей части.
В инициализирующей части (begin как это слово, так и вся эта часть может отсутствовать или быть пустой) размещаются исполняемые операторы, содержащие некоторый фрагмент программы. Эти операторы исполняются до передачи управления основной программе и обычно используются для подготовки ее к работе. Например, в них могут инициализироваться переменные, открываться нужные файлы и т.д.
Для использования в программе модуля или списка модулей необходимо в начале программы поместить оператор uses, после которого уже указывать модули :
program Lalala;
uses aUnit, bUnit, cUnit;
26.Составление функциональных и структурированных тестов.
Функциональные тесты проверяют правильность работы программы по принципу: «не знаю как сделано, но знаю, что должно быть в результате, и именно это и проверяю».
К функциональным тестам относятся:
· «тепличные», проверяющие программу при корректных, нормальных значениях исходных данных
· «экстремальные» («стресс–тесты»), находящиеся на границе области определения (например, наибольшая или наименьшая нагрузка системы по количеству или по времени), проверяющие поведение системы в экстремальных ситуациях, которые могут произойти и на которые программа должна корректно реагировать.
· «запредельные» («тесты обезьяны»), выходящие за границы области определения (а возможно, и здравого смысла), проверяющие ситуации, бессмысленные с точки зрения постановки задачи, но которые могут произойти из-за ошибок пользователя (корректная реакция системы на запрещенный или неподдерживаемый ввод и т.п., так называемая «защита от дурака»)
Структурные тесты контролируют (тестируют) работу всех структурных частей программы (функций, процедур, модулей, основной программы) по всем возможным маршрутам (ветвям программы).
При структурном тестировании необходимо осуществлять контроль:
· обращений к данным (т.е. проверять правильность инициализации переменных; а также размеры массивов и строк; отслеживать, не перепутаны ли строки со столбцами; соответствуют ли входных и выходных значений выбранным типам данных; проверять правильность обращения к файлам и т.п.);
· вычислений (порядок следования операторов и запись выражений; переполнение разрядной сетки или получение машинного нуля; соответствие результата заданной точности и т.п.);
· передачи управления (завершение циклов, функций, программы);
· межмодульных интерфейсов (списки формальных и фактических параметров; отсутствие побочных эффектов, когда подпрограмма изменяет аргументы, которые не должны меняться и т.п.).
Искусство тестирования сводится к разработке простого, полного и не избыточного набора тестов, а технология тестирования – к испытанию программы на всем наборе тестов, после внесения в нее каждого изменения.
20. Нисходящее и восходящее тестирование программ. Достоинства и недостатки. Использование заглушек и драйверов.
Восходящее тестирование.

При восходящем подходе программа собирается и тестируется снизу вверх. Только модули самого нижнего уровня (модули, не вызывающие других модулей) тестируются независимо, автономно. После того как тестирование этих модулей завершено, вызов их должен быть так же надежен, как вызов встроенной функции языка или оператор присваивания. Затем тестируются модули, непосредственно вызывающие уже проверенные. Эти модули более высокого уровня тестируются не автономно, а вместе с уже проверенными модулями более низкого уровня. Процесс повторяется до тех пор, пока не будет достигнута вершина. Здесь завершаются и тестирование модулей, и тестирование сопряжений программы. Для каждого модуля необходимо написать небольшую ведущую программу.

Типы данных Delphi

Теперь обсудим типы данных Delphi, которые программист использует при написании программы. Любая программа на Delphi может содержать данные многих типов:

  • целые и дробные числа,
  • символы,
  • строки символов,
  • логические величины.

Целый тип Delphi

Библиотека языка Delphi включает в себя 7 целых типов данных: Shortint, Smallint, Longint, Int64, Byte, Word, Longword, характеристики которых приведены в таблице ниже.

Вещественный тип Delphi

Кроме того, в поддержку языка Delphi входят 6 различных вещественных типов (Real68, Single, Double, Extended, Comp, Currency), которые отличаются друг от друга, прежде всего, по диапазону допустимых значений, по количеству значащих цифр, по количеству байт, которые необходимы для хранения некоторых данных в памяти ПК (характеристики вещественных типов приведены ниже). Также в состав библиотеки языка Delphi входит и наиболее универсальный вещественный тип — тип Real, эквивалентный Double.

Символьный тип Delphi

Кроме числовых типов, язык Delphi располагает двумя символьными типами:

Тип Ansichar — символы c кодировкой ANSI, им ставятся в соответствие числа от 0 до 255;

Тип Widechar — символы с кодировкой Unicode, им ставятся в соответствие числа от 0 до 65 535.

Строковый тип Delphi

Строковый тип в Delphi обозначается идентификатором string. В языке Delphi представлены три строковых типа:

Тип Shortstring — присущ статически размещаемым в памяти ПК строкам, длина которых изменяется в диапазоне от 0 до 255 символов;

Тип Longstring — этим типом обладают динамически размещаемые в памяти ПК строки с длиной, ограниченной лишь объемом свободной памяти;

Тип WideString — тип данных, использующийся для того, чтобы держать необходимую последовательность Интернациональный символов, подобно целым предложениям. Всякий символ строки, имеющей тип WideString, представляет собой Unicode-символ. В отличие от типа Shortstring, тип WideString является указателем, который ссылается на переменные.

Логический тип Delphi

Логический тип соответствует переменным, которые могут принять лишь одно из двух значений: true, false. В языке Delphi логические величины обладают типом Boolean. Вам были представлены основные типы данных Delphi. Движемся дальше.

System.PAnsiChar

Properties

Description

Defines a null-terminated ANSI string.

PAnsiChar defines a pointer to a memory location that contains AnsiChar values (including the #0 character).

In Delphi, one can obtain a PAnsiChar value from an AnsiString, allowing seamless integration with C or C++ applications that expect null-terminated strings.

PAnsiChar is not supported by the Delphi Next Generation (mobile) compilers, but is used by the Delphi desktop compilers.

  • PAnsiChar is inherently unsafe if used in combination with normal AnsiString values. PAnsiChar variables are not reference-counted and are not copy-on-written. This may result in corruption of the AnsiString values or memory leaks.
  • PAnsiChar is used by the Delphi desktop compilers, but is not supported by the Delphi mobile compilers. For more information, see Migrating Delphi Code to Mobile from Desktop.

Warning: Do not cast non-character pointer types to PAnsiChar to do pointer arithmetic. Instead, use the PByte pointer type, which is declared with the <$POINTERMATH ON>compiler directive.

AnsiChar — Тип Delphi

На этом шаге мы рассмотрим правила использования символьных типов .

По сравнению с реализациями Borland (Turbo) Pascal к традиционному типу Char добавлены типы AnsiChar и WideChar .

Группа символьных типов в Object Pascal так же, как и группа целых типов, разделяется на две категории:

  1. Фундаментальные типы .
  2. Родовые типы .

К фундаментальным относятся типы AnsiChar и WideChar . К родовым типам в группе символьных типов принадлежит только тип Char .

Характеристики символьных типов приведены в таблице 1.

Типы AnsiChar и WideChar имеют постоянное представление в памяти, которое не будет изменяться в различных реализациях Object Pascal . Родовой символьный тип Char в данной реализации соответствует типу AnsiChar . Заметим, что первые 256 символов кода Unicode совпадают с кодом ANSI .

Значение кода требуемого символа можно получить при помощи функции Ord . Обратные действия определения символа по заданному коду выполняются функцией Chr . Кроме того, к значениям символьных типов, как и к значениям других порядковых типов, применимы также функции Pred и Succ .

На следующем шаге мы рассмотрим указательные типы .

Ошибка Delphi 2010 E2010 Несовместимые типы: «AnsiChar» и «Char» — types

Я загрузил некоторый старый код из Delphi Magazine, и когда я его компилирую в Delphi 2010, я получаю несовместимые типы E2010: «AnsiChar» и «Char».

Как устранить эту ошибку?

pAddr: = inet_ntoa (AddrIn.sin_addr);

pAddr, определяемый как PChar
inet_ntoa — это функция, которая возвращает PAnsiChar

    1 2
  • 31 окт 2020 2020-10-31 22:05:28
  • Michael Riley — AKA Gunny

2 ответа

Это зависит от того, что вы пытаетесь с этим сделать. Вы используете адрес самостоятельно или передаете его во внешний код?

Если вы используете его самостоятельно, попробуйте ответить thoiz_vd. Как правило, сохраняйте как можно большую часть своей внутренней строковой обработки в строке. Это сэкономит вам много хлопот.

С другой стороны, если вы передаете его во внешнюю подпрограмму, например, что-то в Windows API, вы должны убедиться, что данные находятся в том формате, который ожидает API. Это немного менее ясно, чем в первом случае, потому что, когда Delphi перешел от AnsiString в UnicodeString в качестве основного типа строки, они отменили много заголовков winapi в модуле Windows , чтобы разрешить эквивалентную широкоформатную версии подпрограмм, в которых были строки.

Итак, проверьте, к чему вы его отправляете. Если для этого требуется PChar , используйте ответ thoiz_vd. Но если он ожидает PAnsiChar , redeclare pAddr как PAnsiChar .

В чем разница между WideChar и AnsiChar?

Я обновляю какой-то древний (с 2003 года) код Delphi для Delphi Architect XE, и у меня есть несколько проблем. Я получаю ряд ошибок, когда есть несовместимые типы. Эти ошибки не происходят в Delphi 6, поэтому я должен предположить, что это происходит потому, что вещи были обновлены.

Я честно не знаю, какая разница между PAnsiChar и PWideChar, но Delphi наверняка знает разницу и не позволит мне скомпилировать. Если бы я знал, каковы различия, возможно, я мог бы выяснить, что использовать или как это исправить.

Короче: до Delphi 2009 собственный тип строк в Delphi использовался как ANSI CHAR: каждый char в каждой строке был представлен как 8 бит char. Начиная с Delphi 2009 строки Delphi стали UNICODE, используя нотацию UTF-16: теперь базовый char использует 16 бит данных (2 байта), и вам, вероятно, не нужно много знать о кодовых точках Unicode, которые представлены как два последовательных символа 16 бит.

8-битные символы называются «Ansi Chars». PAnsiChar является указателем на 8-битные символы. 16-битные символы называются «Широкие символы». PWideChar является указателем на 16-битные символы. Delphi знает разницу и хорошо, если не позволяет вам смешивать два!

Дополнительная информация

Вы можете найти дополнительную информацию о переносе Delphi в Unicode здесь: Новая справочная информация: миграция Unicode в Delphi для простых смертных

Вы также можете найти SO для «миграции Unicode Delphi».

Несколько лет назад тип символа по умолчанию в Delphi был изменен с AnsiChar (однобайтная переменная, представляющая символ ANSI) на WideChar (двухбайтная переменная, представляющая символ UTF16.) Тип char теперь является псевдонимом WideChar вместо AnsiChar , тип string теперь является псевдонимом UnicodeString (UIF-16 Unicode версии традиционного типа строки Delphi) вместо AnsiString , а PChar > теперь является псевдонимом PWideChar вместо PAnsiChar .

Компилятор может позаботиться о большом количестве самих конверсий, но есть несколько проблем:

  • Если вы используете типы указателей строк, например PChar , вам нужно убедиться, что ваш указатель указывает на нужный тип данных, и компилятор не всегда может это проверить.
  • Если вы передаете строки параметрам var, тип переменной должен быть точно таким же. Теперь это может быть более сложным, если у вас есть два типа строк.
  • Если вы используете string как удобный буфер байтового массива для хранения произвольных данных вместо переменной, содержащей текст, это не будет работать как UnicodeString . Убедитесь, что они объявлены как RawByteString в качестве обходного пути.
  • В любом случае, когда вы работаете со строковыми байтами, например, при чтении или записи в/из TStream, убедитесь, что ваш код не предполагает, что char длится один байт.

Посмотрите Delphi Unicode Migration for Mere Mortals для получения более трюков и советов о том, как заставить это работать. Это не так сложно, как кажется, но это тоже не тривиально. Удачи!

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL
Type Visibility Source Unit Parent