Как делает WriteLn (), действительно работают?

Когда включен активный режим или в TF 2.0, example ,= dataset.take(1) возвращает кортеж (данные, метку), в данном случае это единственный обучающий пример. И example = dataset.take(1) вернет tensorflow.python.data.ops.dataset_ops.DatasetV1Adapter объект.

12
задан Wouter van Nifterick 6 March 2009 в 04:04
поделиться

9 ответов

Writeln - то, что мы вызываем функцию "волшебства" компилятора. Если Вы посмотрите в System.pas, то Вы не найдете Writeln, который объявляется чем-либо как то, что Вы ожидали бы. Компилятор буквально разламывает все это на отдельные вызовы к различным специальным функциям библиотеки времени выполнения.

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

25
ответ дан 2 December 2019 в 03:54
поделиться

Насколько я знаю, стандарты Паскаля не включают аргументы переменной.

Однако IIRC, GNU, Паскаль позволяет нам, Вы говорите что-то как: Procecdure Foo (a: Целое число; b: Целое число;...);

Попытайтесь искать в документах языка своего компилятора "Списки Аргумента переменной" или "совместимые массивы". Вот пример позже: http://www.gnu-pascal.de/demos/conformantdemo.pas.

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

Однако, если Вы не пишете функцию "writeln" (который уже записан), Вы, вероятно, не должны реализовывать процедуру с аргументы переменной. Попробуйте повторение или рекурсию вместо этого :)

2
ответ дан 2 December 2019 в 03:54
поделиться

Поскольку Allen сказал, что Вы не можете записать свою собственную функцию, которая делает весь одинаковый вещи.

Можно, однако, записать драйвер текстового файла, который делает что-то пользовательское и когда Запись стандарта использования (ln) для записи в драйвер текстового файла. Мы сделали это в Вас старые дни DOS :)

("Драйвер" в контексте предыдущего оператора является просто частью кода Паскаля, который сцепляется в систему путем переключения указателя в Системной единице IIRC. Долгое время, так как я в последний раз использовал этот прием.)

4
ответ дан 2 December 2019 в 03:54
поделиться

Да, можно сделать это в Delphi и друзьях (например, свободный Паскаль, Kylix, и т.д.), но не в более "стандартных" паскалях. Ищите различные открытые параметры массива, которые используются с синтаксисом что-то вроде этого:

procedure MyProc(args : array of const);

(это были несколько лет, и у меня нет руки руководств, так проверьте детали прежде, чем продолжиться). Это дает Вам открытый массив TVarData (или что-то как этот), что можно извлечь RTTI из.

Одно примечание, хотя: Я не думаю, что Вы сможете соответствовать синтаксису форматирования x:y (который является особенным), и должен будет, вероятно, пойти с немного большим количеством подробной обертки.

1
ответ дан 2 December 2019 в 03:54
поделиться

Большинство уже сказано, но мне нравится добавлять несколько вещей.

Сначала можно использовать функцию Формата. Замечательно преобразовать почти любой вид переменной, чтобы представить в виде строки и управлять ее размером. Хотя это имеет свои дефекты:

myvar := 1;
while myvar<10000 do begin
  Memo.Lines.Add(Format('(%3d)', [myVar]));
  myvar := myvar * 10;
end;

Производит:

(  1)
( 10)
(100)
(1000)

Таким образом, размер является минимальным размером (точно так же, как :x:y конструкция).

Для получения минимального количества аргументов переменной можно работать с параметрами по умолчанию и перегруженными функциями:

procedure WriteSome(const A1: string; const A2: string = ''; const A3: string = '');

или

procedure WriteSome(const A1: string); overload;
procedure WriteSome(const A1: Integer); overload;
1
ответ дан 2 December 2019 в 03:54
поделиться

Вы не можете записать свой собственный write/writeln в старом Паскале. Они сгенерированы компилятором, форматированием, выравниванием, и т.д. Вот почему некоторые программисты как язык C, даже гибкие стандартные функции, например, printf, scanf, могут быть реализованы любыми компетентными программистами.

Можно даже создать идентичную функцию printf для C, если Вы склонны создать что-то более производительное, чем то, реализованное поставщиком C. Нет никакого волшебного обмана в них, Ваш код просто должен "обойти" аргументы переменной.

P.S.

Но поскольку MarkusQ указали, некоторые варианты Паскаля (Свободный Паскаль, Kylix, и т.д.) могут упростить аргументы переменной. Я в последний раз переделываю Паскаля, со дней DOS, Turbo Pascal 7.

1
ответ дан 2 December 2019 в 03:54
поделиться

Writeln не основан на "массиве констант", а разлагается компилятором на различные вызовы, которые преобразуют аргументы в строку, а затем вызывают примитивную строку записи. «LN» - это просто функция, которая записывает окончание строки в виде строки. (Зависит от ОС). Переменные процедуры (указатели на функции) для примитивов являются частью типа файла (Textrec / filerec), поэтому их можно настраивать. (например, AssignCrt в TP)

Если включен режим {$ I +}, после каждого элемента выполняется вызов функции iocheck.

Конструкция GPC, созданная выше, похожа на безграничный открытый массив C. FPC (и afaik Delphi тоже) поддерживает это, но с другим синтаксисом.

процедура somehting (a: массив констант); cdecl;

будет преобразована, чтобы быть совместимой с ABI в стиле C, printf. Это означает, что соответствующая функция (в данном случае somehting) не может получить количество аргументов, но должна полагаться на синтаксический анализ строки форматирования. Это что-то отличное от array of const, что безопасно.

1
ответ дан 2 December 2019 в 03:54
поделиться
[

] Хотя это и не прямой ответ на ваш вопрос, я хотел бы добавить следующий комментарий: Недавно я переписал код, используя синтаксис Writeln(...), на использование StringList, заполняя 'строки' функцией Format(...) и просто IntToStr(...), функциями FloatToStr(...) и т.п.[

] [

]Основной причиной такого изменения было повышение скорости. Использование StringList и SaveFileTo намного, намного быстрее, чем комбинация WriteLn, Write. [

] [

] Если вы пишете программу, которая создает много текстовых файлов (я работал над программой для создания сайтов), то это многое меняет.[

].
1
ответ дан 2 December 2019 в 03:54
поделиться

Это магическое поведение компилятора, а не обычная процедура. И нет, писать такие подпрограммы (к сожалению!) невозможно. Генерация кода разрешает счет актуальных параметров и их типов и транслирует их в соответствующие вызовы RTL (например, Str()) во время компиляции. Это противоположно часто предлагаемому массиву const (на самом деле формальному параметру массива одного варианта), что приводит к такому же результату во время выполнения. Позже я нахожу подход неуклюжим, это несколько ухудшает читабельность кода, и Bugland (Borland/Inprise/Codegear/Embarcadero/name it) сломал Code Insight для вариантов открытых конструкторов массивов (да, мне не все равно, я использую OutputDebugString(PChar(Format('...', [...])))) и завершение кода там не работает корректно (или вообще не работает)). Таким образом, наиболее близкий способ симулирования магического поведения - объявление множества перегруженных подпрограмм (на самом деле их очень много, по одной на конкретный тип формального параметра в конкретной позиции). Можно назвать это тоже kludge, но это единственный способ получить гибкость списка переменных параметров и может быть скрыто в отдельном модуле.

PS: я специально пропустил спецификаторы формата, так как синтаксис не позволяет использовать точки с запятой, где Str(), Write() и Writeln() их принимают.

2
ответ дан 2 December 2019 в 03:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: