<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MikeSoft &#187; Метки &#187; программирование</title>
	<atom:link href="http://mikesoft.ws/tag/%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5/feed/" rel="self" type="application/rss+xml" />
	<link>http://mikesoft.ws</link>
	<description>Practical Software</description>
	<lastBuildDate>Sun, 15 Nov 2009 10:37:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Отправим Goto на пенсию!</title>
		<link>http://mikesoft.ws/2008/01/12/goto/</link>
		<comments>http://mikesoft.ws/2008/01/12/goto/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 14:30:34 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[программирование]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=119</guid>
		<description><![CDATA[Все кто учил язык BASIC, наверно помнят оператор безусловного перехода GOTO. Почему BASIC? Не только он, конечно, просто в ранних реализациях BASIC (например, Microsoft QuickBasic, входивший в свое время в поставку MS-DOS) он применялся действительно часто. Ведь там не было ни классов, ни операторов обрыва циклов и выполнения вроде Break, Exit, Continue, а также исключений. [...]]]></description>
			<content:encoded><![CDATA[<p>Все кто учил язык BASIC, наверно помнят оператор безусловного перехода GOTO. Почему BASIC? Не только он, конечно, просто в ранних реализациях BASIC (например, Microsoft QuickBasic, входивший в свое время в поставку MS-DOS) он применялся действительно часто. Ведь там не было ни классов, ни операторов обрыва циклов и выполнения вроде Break, Exit, Continue, а также исключений. В современных же языках с полноценными средствами структурного программирования, использование Goto считается крайне дурным тоном, так как затрудняет чтение и делает код непредсказуемым. <em>Доводы против оператора goto</em> четко выписаны в одноименной <a href="http://khpi-iip.mipk.kharkiv.edu/library/extent/dijkstra/pp/ewd215.html">статье Эдсгера Дейкстры</a>. Но я решил идти не по тропе теоретических изысканий, а показать на практике, что код БЕЗ GOTO может быть не только красивее и логичнее, но и в разы быстрее.</p>
<p><span id="more-119"></span></p>
<p>Существовала когда-то библиотека компонентов для Delphi под названием RX Library. Для своего времени это была отличная библиотека, содержала множество полезных компонентов и функций. Со временем библиотека перестала разиваться, теперь она только адаптируется к новым версиям Delphi, для поддержания обратной совместимости (<a href="http://rx.delphiplus.org/">http://rx.delphiplus.org/</a>, <a title="http://sourceforge.net/projects/rxlib/" href="http://sourceforge.net/projects/rxlib/">http://sourceforge.net/projects/rxlib/</a>). Код этой библиотеки без существенных изменений (кроме названий компонентов) был перенесен в <a href="http://homepages.borland.com/jedi/jvcl/">JEDI VCL</a>.</p>
<p>Вместе с множеством полезных RTL-функций была унаследована и функция перевода чисел из десятичной системы счисления в римскую. История этой функции мне неизвестна, но её главной особенностью является наличие оператора безусловного перехода goto (модули <a href="http://rxlib.svn.sourceforge.net/viewvc/*checkout*/rxlib/trunk/Units/rxStrUtils.pas?revision=17">rxStrUtils</a>, <a href="http://jvcl.svn.sourceforge.net/viewvc/*checkout*/jvcl/trunk/jvcl/run/JvJCLUtils.pas">JvJCLUtils</a>):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
</pre></td><td class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> IntToRoman<span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Longint</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">Label</span>
  A500<span style="color: #000066;">,</span> A400<span style="color: #000066;">,</span> A100<span style="color: #000066;">,</span> A90<span style="color: #000066;">,</span> A50<span style="color: #000066;">,</span> A40<span style="color: #000066;">,</span> A10<span style="color: #000066;">,</span> A9<span style="color: #000066;">,</span> A5<span style="color: #000066;">,</span> A4<span style="color: #000066;">,</span> A1<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">''</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> <span style="color: #0000ff;">1000</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">1000</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'M'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">900</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A500
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">900</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'CM'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A90<span style="color: #000066;">;</span>
A400<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">400</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A100
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">400</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'CD'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A90<span style="color: #000066;">;</span>
A500<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">500</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A400
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">500</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'D'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
A100<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> <span style="color: #0000ff;">100</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">100</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'C'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
A90<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">90</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A50
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">90</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'XC'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A9<span style="color: #000066;">;</span>
A40<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">40</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A10
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">40</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'XL'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A9<span style="color: #000066;">;</span>
A50<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">50</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A40
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">50</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'L'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
A10<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> <span style="color: #0000ff;">10</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">10</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'X'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
A9<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">9</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A5
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'IX'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Exit</span><span style="color: #000066;">;</span>
A4<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">4</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A1
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'IV'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Exit</span><span style="color: #000066;">;</span>
A5<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">5</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A4
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">5</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'V'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A1<span style="color: #000066;">;</span>
A1<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'I'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>Была ли эта функция переведена дословно с языка BASIC или написана с нуля &mdash; теперь это не так уж важно. Главное, что в современном программировании GOTO нет места. И эта моя публикация нацелена на то, чтобы в очередной раз это подтвердить. Несмотря на отдельные доводы в пользу оператора GOTO: например, что он обеспечивают лучшую производительность по сравнению со стандартными методами структурного программирования.</p>
<p>Если не смотреть на вышеприведенный код (так как в нем с трудом можно что-то понять, только сбить себя с толку), а задаться целью написать функцию перевода в римскую систему счисления с нуля, то она будет выглядеть примерно так:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> IntToRoman<span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Longint</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">type</span>
  TRomanRec <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
    <span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
    Amount<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">const</span>
  Roman<span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000066;">&#91;</span>1<span style="color: #000066;">..</span>13<span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> TRomanRec <span style="color: #000066;">=</span> <span style="color: #000066;">&#40;</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'M'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span> <span style="color: #0000ff;">1000</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'CM'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">900</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'D'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">500</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'CD'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">400</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'C'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">100</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'XC'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">90</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'L'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">50</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'XL'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">40</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'X'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">10</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'IX'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">9</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'V'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">5</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'IV'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">4</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'I'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span>
  <span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  R<span style="color: #000066;">:</span> TRomanRec<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">''</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">for</span> R <span style="color: #000000; font-weight: bold;">in</span> Roman <span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> R<span style="color: #000066;">.</span><span style="color: #000066;">Str</span><span style="color: #000066;">;</span>
      <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>Здесь реализован простейший алгоритм перевода. Последовательно вычитая из исходного числа значения римских чисел или их сочетаний, мы получаем строковое представление данного числа. Что касается производительности, то эта функция действительно несколько медленнее варианта с GOTO. От 8% до 30% в зависимости от диапазона чисел (чем больше &mdash; тем меньше разница, 8% на переводе чисел от единицы до миллиона). Сторонники GOTO радостно возликовали бы на этом месте и успокоились, продолжая использовать функцию с GOTO. Но я как сторонник структурного программирования решил на этом не останавливаться, а проанализировать внимательно алгоритм.</p>
<p>Первое узкое место, которое бросается в глаза &mdash; формирование строки в цикле. Мало того, что такая операция является ресурсоемкой, приводя к лишним операциям выделения памяти, она гораздо медленнее, чем простая функция div, которую было бы достаточно выполнить всего один раз для одной римской цифры. Она возвратила бы количество римских чисел, а сформировать строку можно было бы функцией StringOfChar (модуль SysUtils), которая написана на ассемблере и имеет отличную производительность.</p>
<p>Но здесь всплывает иная сложность: как формировать строку из нескольких символов (таких как промежуточные значения CM=900, CD=400 и т.д.). Здесь два варианта: либо писать универсальную функцию, которая будет формировать строку не из символов, а из одинаковых строковых фрагментов, либо отказаться от промежуточных значений. Первый вариант существенно снизит производительность, поэтому возьмемся за другой вариант. В нем не все так сложно, как могло бы показаться на первый взгляд. Если внимательно посмотреть на ряд римских чисел</p>
<pre>
I, V, X, L, C, D, M</pre>
<p>то можно заметить, что отниматься от большего числа могут только числа через одно (на нечетных местах). Это правило не касается только тысячи (M), так как нету большего числа в римской системе счисления. Такой алгоритм несложно реализовать:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> IntToRomanOptimized<span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Longint</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">type</span>
  TRomanRec <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
    Symbol<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Char</span><span style="color: #000066;">;</span>
    Amount<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Word</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">const</span>
  <span style="color: #808080; font-style: italic;">// Отмеченные &quot;+&quot; элементы используются для уменьшения предыдущих значений,</span>
  <span style="color: #808080; font-style: italic;">// все они на нечетных местах </span>
  Roman<span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000066;">&#91;</span>1<span style="color: #000066;">..</span>7<span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> TRomanRec <span style="color: #000066;">=</span> <span style="color: #000066;">&#40;</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'M'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span> <span style="color: #0000ff;">1000</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 1</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'D'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">500</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 2</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'C'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">100</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 3 +</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'L'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">50</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 4</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'X'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">10</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 5 +</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'V'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">5</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 6</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'I'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span>   <span style="color: #808080; font-style: italic;">// 7 +</span>
  <span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  I<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  R<span style="color: #000066;">:</span> TRomanRec<span style="color: #000066;">;</span>  
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">''</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Low</span><span style="color: #000066;">&#40;</span>Roman<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">to</span> <span style="color: #000066;">High</span><span style="color: #000066;">&#40;</span>Roman<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">begin</span>
    R <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Roman<span style="color: #000066;">&#91;</span>I<span style="color: #000066;">&#93;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">if</span> Value &gt;<span style="color: #000066;">=</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #000066;">StringOfChar</span><span style="color: #000066;">&#40;</span>R<span style="color: #000066;">.</span><span style="color: #006600;">Symbol</span><span style="color: #000066;">,</span> Value <span style="color: #000000; font-weight: bold;">div</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> Value <span style="color: #000000; font-weight: bold;">div</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000066;">*</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> &gt; <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">then</span>
      <span style="color: #000000; font-weight: bold;">with</span> Roman<span style="color: #000066;">&#91;</span>I <span style="color: #000066;">+</span> <span style="color: #000066;">Ord</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">Odd</span><span style="color: #000066;">&#40;</span>I<span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">+</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #000000; font-weight: bold;">if</span> Value &gt;<span style="color: #000066;">=</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000066;">-</span> Amount <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #000000; font-weight: bold;">begin</span>
          Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> Symbol <span style="color: #000066;">+</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Symbol</span><span style="color: #000066;">;</span>
          <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000066;">-</span> Amount<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>Новый вариант функции готов, теперь перейдем к тестированию производительности. И она не может не радовать! На переводе чисел от 1 до 100 000 оптимизированный вариант работает в 2 раза быстрее, чем с GOTO. На 200&nbsp;000 &mdash; в 3 раза быстрее, на 300&nbsp;000 &mdash; в 4 раза, а на числах до миллиона &mdash; более чем в 13 (!) раз быстрее. И это еще раз подтверждает, что GOTO пора на пенсию, время грамотного программирования!</p>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2008/01/12/goto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
