<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=57791&amp;view=findpost&amp;p=536022</guid>
        <pubDate>Tue, 07 Dec 2004 23:18:22 +0000</pubDate>
        <title>Приведение типов</title>
        <link>https://forum.sources.ru/index.php?showtopic=57791&amp;view=findpost&amp;p=536022</link>
        <description><![CDATA[RADIX: А теперь развеем миф о том, что Pascal не даст вам выстрелить себе в ногу  :D  :yes: <br>
(здесь и далее имеется в виду BP/TP)<br>
<br>
Есть универсальный способ приведения типа, обходящий встроенный в компилятор контроль размеров.<br>
В этом способе используются два факта:<br>
<br>
1)разыменованный бестиповой указатель типа pointer совместим по приведению с любым типом;<br>
<br>
2)тип PChar можно складывать со смещением, в результате двигаясь по памяти;<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;W : word &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 12345; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ = 39 }</div><div class="code_line">&nbsp;&nbsp;B : array[0..3]of byte =(1,2,3,4); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { = 030201 }</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp;{ стандарт -----------------------------------------------------------------------------------}</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;W=&#39;,W:5,&#39; B[0]=&#39;,B[0]:3,&#39; B[1]=&#39;,B[1]:3); {&#39;W=12345 B[0]= &nbsp;1, B[0]= &nbsp;2&#39; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp;{ классическое приведение типа ---------------------------------------------------------------}</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Lo(W)=&#39;,byte(W):3); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;Lo(W)= 57&#39; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 57 =  &nbsp;}</div><div class="code_line">&nbsp;&nbsp;{ прицел на ногу -----------------------------------------------------------------------------}</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Word(B[0],B[1])=&#39;,word((@B)^):5); &nbsp; &nbsp; &nbsp; &nbsp; {&#39;Word(B[0],B[1])= &nbsp;513&#39; &nbsp; &nbsp; &nbsp; &nbsp;513 = 01}</div><div class="code_line">&nbsp;&nbsp;{ прицел выше --------------------------------------------------------------------------------}</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Hi(W)=&#39;,byte((PChar(@W)+1)^):3); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&#39;Hi(W)= 48&#39; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 48 =  &nbsp;}</div><div class="code_line">&nbsp;&nbsp;{ контрольный выстрел в голову ---------------------------------------------------------------}</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Word(B[2],B[3])=&#39;,word((pointer(PChar(@B)+2))^):5);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&#39;Word(B[2],B[3])= 1027&#39; &nbsp; &nbsp; &nbsp; 1027 = 03}</div><div class="code_line">end.</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script>]]></description>
        <author>RADIX</author>
        <category>Pascal: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=57791&amp;view=findpost&amp;p=386884</guid>
        <pubDate>Wed, 23 Jun 2004 07:44:00 +0000</pubDate>
        <title>Приведение типов</title>
        <link>https://forum.sources.ru/index.php?showtopic=57791&amp;view=findpost&amp;p=386884</link>
        <description><![CDATA[e-moe: <strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Тождественные и совместимые типы</span></strong><br>
<br>
При передаче и преобразовании информации в программе должны соблюдаться некоторые требования, блокирующие некорректные действия программиста. Эти требования могут быть разделены на три группы, соответствующие следующим случаям:<ol class="tag-list" type="1"><li>передача фактического параметра-переменной;</li><li>вычисление выражения;</li><li>выполнение оператора присваивания и передача фактического параметра-значения.</li></ol><br>
В первом случае должны быть выполнены требования <em class='tag-i'>тождественности</em> типов, во втором – <em class='tag-i'>совместимости</em> типов, в третьем – <em class='tag-i'>совместимости по присваиванию</em>.<br>
<br>
<strong class='tag-b'>Тождественность типов.</strong><br>
<br>
Рассмотрим процедуру, в списке формальных параметров которой заданы лишь параметры-переменные (перед именем формального параметра записано слово <strong class='tag-b'>Var</strong>).<br>
<br>
Пример 1.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Type &nbsp;Ar1 = array[1..100] of real;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Ar2 = array[1..100] of real;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Ar3 = Ar1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Ar4 = Ar3;</div><div class="code_line">Var &nbsp;X : Ar1; &nbsp;Y : Ar2; &nbsp;Z : Ar3; &nbsp;W : Ar4;</div><div class="code_line">&nbsp;&nbsp; &nbsp; a,b : real;</div><div class="code_line">&nbsp;&nbsp; &nbsp; m,n : integer;</div><div class="code_line">Procedure Proc1(Var D:Ar1; Var k:integer);</div><div class="code_line">Begin</div><div class="code_line">..........................</div><div class="code_line">End { Proc1 };</div></ol></div></div></div></div><br>
<br>
Ранее было указано, что формальный и соответствующий ему фактический параметр должны иметь одно и то же имя типа. Это не совсем точно.<br>
Обозначим через <strong class='tag-b'>Type1</strong> имя типа формального параметра, через <strong class='tag-b'>Type2</strong> - имя типа соответствующего ему фактического параметра.<br>
Как известно, при обращении к процедуре фиктивный адрес формального параметра-переменной замещается реальным адресом фактического параметра. В этом случае формальная и фактическая переменные соответствуют одному и тому же полю памяти. Следовательно, имена типов <strong class='tag-b'>Type1</strong> и <strong class='tag-b'>Type2</strong> этих переменных должны определять переменные одинакового размера и структуры, с одинаковым множеством допустимых значений и операций по их обработке. Последнее возможно, если типы <strong class='tag-b'>Type1</strong> и <strong class='tag-b'>Type2</strong> тождественны.<br>
<br>
Два типа считаются тождественными, если они представляют собой одно и то же имя типа или один из них описан как эквивалентный другому типу.<br>
В примере 1 типы <strong class='tag-b'>Ar1</strong>, <strong class='tag-b'>Ar3</strong> и <strong class='tag-b'>Ar4</strong> тождественны, <strong class='tag-b'>Ar1</strong> и <strong class='tag-b'>Ar2</strong> - не тождественны, хотя они и имеют одинаковое описание типа. Поэтому обращения к процедуре <strong class='tag-b'>Proc1(X,m)</strong>, <strong class='tag-b'>Proc1(Z,m)</strong> и <strong class='tag-b'>Proc1(W,m)</strong> считаются правильными, а при обращении <strong class='tag-b'>Proc1(Y,m)</strong> будет выведено сообщение &quot;<strong class='tag-b'>Type mismatch</strong>&quot; (&quot;Несоответствие типов&quot;).<br>
<br>
<strong class='tag-b'>Совместимость типов. Рассмотрим пример 2.</strong><br>
<br>
Пример 2.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Var &nbsp;x,y : real;</div><div class="code_line">&nbsp;&nbsp; &nbsp; m,n : integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp; ch : char;</div><div class="code_line">&nbsp;&nbsp; &nbsp; b : boolean;</div><div class="code_line">Begin &nbsp;...............</div><div class="code_line">&nbsp;&nbsp;y:=x+2*ch;</div><div class="code_line">&nbsp;&nbsp;b:=(x&#60;ch) and n;</div></ol></div></div></div></div><br>
<br>
Вполне очевидно, что выражения в правой части операторов присваивания не могут быть вычислены, поскольку лишены смысла арифметические операции по отношению к символьным переменным, сравнение числовых и символьных переменных и т.п. В этих выражениях нарушены требования совместимости типов.<br>
<br>
Основные правила совместимости типов:<br>
- операнды выражения имеют численные типы (вещественный, целочисленный, диапазонный);<br>
- операнды определены логическим типом;<br>
- операнды имеют строковый, символьный  или диапазонный символьный типы.<br>
Если операнды выражения имеют различные численные типы, то при выполнении арифметических операций производится преобразование их значений к более старшему типу в соответствии со следующими приоритетами:<br>
   - <strong class='tag-b'>real</strong>;<br>
   - <strong class='tag-b'>longint</strong>;<br>
   - <strong class='tag-b'>integer, word</strong>;<br>
   - <strong class='tag-b'>shortint, byte</strong>.<br>
<br>
<strong class='tag-b'>Совместимость типов по присваиванию.</strong> Рассмотрим пример 3.<br>
<br>
Пример 3.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Var &nbsp;x,y : real;</div><div class="code_line">&nbsp;&nbsp; &nbsp; m,n : integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp; ch : char;</div><div class="code_line">&nbsp;&nbsp; &nbsp; b : boolean;</div><div class="code_line">Begin &nbsp;...............</div><div class="code_line">&nbsp;&nbsp;{ 1 } y:=(m&#60;n) and b;</div><div class="code_line">&nbsp;&nbsp;{ 2 } ch:=x+m;</div><div class="code_line">&nbsp;&nbsp;{ 3 } m:=2*x+y;</div><div class="code_line">&nbsp;&nbsp;{ 4 } y:=3*m-n;</div></ol></div></div></div></div><br>
<br>
Числовой переменной нельзя присвоить булевское значение, символьной переменной - численное значение. Поэтому операторы <strong class='tag-b'>1</strong> и <strong class='tag-b'>2</strong> не могут быть выполнены, здесь нарушается требование совместимости по присваиванию.<br>
В правой части оператора <strong class='tag-b'>3</strong> - вещественное значение, в левой части - целочисленная переменная. Если допустить выполнение такого оператора, то дробная часть вещественного значения должна быть отброшена, т.е. произошла бы потеря точности. В связи с этим считается, что в операторе <strong class='tag-b'>3</strong> также нарушаются требования совместимости по присваиванию.<br>
В операторе <strong class='tag-b'>4</strong> потеря точности не наблюдается. При его выполнении производится лишь преобразование целочисленного значения, полученного при вычислении выражения в правой части оператора, к типу <strong class='tag-b'>real</strong>. <br>
Обозначим тип переменной в левой части <strong class='tag-b'>Type1</strong>, тип значения выражения - <strong class='tag-b'>Type2</strong>.<br>
Основные требования совместимости по присваиванию:<br>
- <strong class='tag-b'>Type1 и Type2 </strong>имеют тождественные типы и ни один из них не является файловым типом;<br>
- <strong class='tag-b'>Type1 и Type2 </strong>- целочисленные типы;<br>
- <strong class='tag-b'>Type1 </strong>- вещественный тип, <strong class='tag-b'>Type2 </strong>- вещественный или целочисленный тип;<br>
- <strong class='tag-b'>Type1 и Type2 </strong>- строковые типы;<br>
- <strong class='tag-b'>Type1 </strong>- строковый тип, <strong class='tag-b'>Type2 </strong>- символьный тип.<br>
<br>
Более жесткие требования должны соблюдаться, когда в левой и правой частях оператора присваивания записаны составные переменные, в частности, массивы.<br>
<br>
Пример 4.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Type &nbsp;Ar1 = array[1..100] of real;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Ar2 = array[1..100] of real;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Ar3 = Ar1;</div><div class="code_line">Var &nbsp; X,Y : Ar1; &nbsp;Z : Ar2; &nbsp;W : Ar3;</div></ol></div></div></div></div><br>
<br>
Здесь типы <strong class='tag-b'>Type1</strong> и <strong class='tag-b'>Type2</strong> должны быть тождественными. Следовательно, в этом случае операторы <strong class='tag-b'>Y:=X</strong> и <strong class='tag-b'>Y:=W</strong> являются допустимыми, в то время как для оператора <strong class='tag-b'>Y:=Z</strong> будет определено несоответствие типов.<br>
<br>
Рассмотрим теперь процедуру, в списке формальных параметров которой имеются параметры-значения.<br>
<br>
Пример 5.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Var &nbsp;x,y : real;</div><div class="code_line">&nbsp;&nbsp; &nbsp; m,n : integer;</div><div class="code_line">Procedure Proc2(k:integer; r,t:real);</div><div class="code_line">Begin</div><div class="code_line">.............</div><div class="code_line">End { Proc2 };</div><div class="code_line">Begin</div><div class="code_line">.............</div><div class="code_line">&nbsp;&nbsp;{ 1 } Proc2(m,n-1,x+m);</div><div class="code_line">&nbsp;&nbsp;{ 2 } Proc2(y,x+y,x);</div></ol></div></div></div></div><br>
<br>
Для параметра-значения в теле процедуры выделяется поле памяти в соответствии с его типом. При обращении к процедуре в это поле пересылается значение фактического параметра; другими словами, формальному параметру присваивается значение фактического параметра. Следовательно, по отношению к параметру-значению должны соблюдаться изложенные выше требования совместимости по присваиванию. В частности, в примере 5 для оператора 1 эти требования соблюдаются, для оператора 2 - не соблюдаются.<br>
<br>
<br>
<br>
<br>
<strong class='tag-b'>ПРИВЕДЕНИЕ ТИПОВ ПЕРЕМЕННЫХ</strong><br>
<br>
Имя любой переменной, объявленной в разделе <strong class='tag-b'>Var</strong>, - это адрес поля памяти в машинной программе. Оператор присваивания <strong class='tag-b'>a:=b</strong>, рассматриваемый на уровне машинной программы, - это пересылка содержимого поля памяти b в поле памяти a.<br>
При программировании на машинном языке или на языке ассемблера произвольному полю памяти можно присвоить значение любого другого поля памяти. В этом случае ответственность за правильность выполнения оператора присваивания полностью возлагается на программиста.<br>
Иная ситуация имеет место при программировании на языках высокого уровня, в частности на языке Паскаль. Имя переменной, идентифицирующей адрес поля памяти, всегда имеет вполне определенный тип. Тип переменной однозначно определяет множество значений, которые имеет право принимать переменная данного типа, и набор операций, которые допустимы при ее обработке.<br>
<br>
Пример.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Var &nbsp;k,m : byte;</div><div class="code_line">&nbsp;&nbsp; &nbsp; p,q : char;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp;k:=65; p:=&#39;A&#39;;</div><div class="code_line">&nbsp;&nbsp;1) m:=k; q:=p;</div><div class="code_line">&nbsp;&nbsp;2) m:=p; q:=k;</div><div class="code_line">&nbsp;&nbsp;3) m:=ord(p); q:=chr(k);</div></ol></div></div></div></div><br>
<br>
Внутреннее представление переменной <strong class='tag-b'>k</strong> и переменной <strong class='tag-b'>p</strong> совершенно одинаково (порядковый номер символа &#39;<strong class='tag-b'>A</strong>&#39; в таблице <strong class='tag-b'>ASCII</strong> равен 65) и имеет вид <strong class='tag-b'>0110 0101</strong>.<br>
Действие оператора <strong class='tag-b'>m:=k</strong> сводится к пересылке содержимого однобайтного поля <strong class='tag-b'>k</strong> в поле <strong class='tag-b'>m</strong>. Аналогичные действия выполняются для оператора <strong class='tag-b'>q:=p</strong>. В то же время операторы <strong class='tag-b'>m:=p</strong> и <strong class='tag-b'>q:=k</strong> не могут быть выполнены, так как при их трансляции будет обнаружено несоответствие типов.<br>
Пересылка содержимого поля p в поле m может быть выполнена оператором  <strong class='tag-b'>m:=ord(p)</strong>. Функция <strong class='tag-b'>ord</strong> не производит никаких преобразований значения переменной <strong class='tag-b'>p</strong>, она лишь информирует транслятор, что значение этой переменной следует рассматривать как значение целочисленной переменной и переслать соответственно в поле <strong class='tag-b'>m</strong>. Аналогичная ситуация имеет место для оператора  <strong class='tag-b'>q:=chr(k)</strong>. Следовательно, функции <strong class='tag-b'>ord</strong> и <strong class='tag-b'>chr</strong>выполняют приведение типа, а не преобразование значений переменных.<br>
<br>
При программировании на Паскале может возникать необходимость рассматривать одно и то же поле памяти как значения переменных самых различных типов, а не только типов <strong class='tag-b'>char</strong> и <strong class='tag-b'>byte</strong>. В этом случае используют аппарат приведения типа переменных, с помощью которого обращение к переменной одного типа может рассматриваться как обращение к переменной другого типа.<br>
<br>
Синтаксис приведения типа:<br>
<br>
<strong class='tag-b'>идентификатор типа + &#39;(&#39; + идентификатор переменной + &#39;)&#39;</strong><br>
<br>
Здесь поле памяти, определяемое идентификатором переменной, рассматривается как экземпляр типа, представленного идентификатором типа.<br>
<br>
Рассмотрим суть приведения типов в Турбо Паскале на следующих двух примерах.<br>
<br>
Пример 1.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Var &nbsp;ch : char;</div><div class="code_line">&nbsp;&nbsp; &nbsp; b1,b2 : byte;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp;ch:=&#39;A&#39;; b1:=byte(ch); b2:=ord(ch);</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;b1=&#39;,b1,&#39; &nbsp; b2=&#39;,b2);</div></ol></div></div></div></div><br>
<br>
Будет отпечатано:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">b1=65 &nbsp; b2=65</div></ol></div></div></div></div><br>
Выражение <strong class='tag-b'>byte(ch)</strong> определяет &quot;наложение&quot; типа <strong class='tag-b'>byte</strong> на переменную <strong class='tag-b'>ch</strong>. В этом случае биты, содержащиеся в поле памяти <strong class='tag-b'>ch</strong>, интерпретируются как значение переменной типа <strong class='tag-b'>byte  (ch = 010000012 = 4116 = 6510).</strong><br>
Примечание. Внешняя форма записи выражения <strong class='tag-b'>byte(ch)</strong> и функции <strong class='tag-b'>ord(ch)</strong> одинакова, что позволяет трактовать выражение <strong class='tag-b'>byte(ch</strong>) как функцию приведения к типу <strong class='tag-b'>byte</strong>.<br>
<br>
Пример 2.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Type &nbsp;ByteAr = array[1..2] of byte;</div><div class="code_line">Var &nbsp;W : word;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp;ByteAr(W)[1]:=10; ByteAr(W)[2]:=20;</div><div class="code_line">&nbsp;&nbsp;Writeln(W,&#39; &nbsp; &#39;,ByteAr(W)[1],&#39; &nbsp; &#39;,ByteAr(W)[2]);</div><div class="code_line">&nbsp;&nbsp;W:=2500;</div><div class="code_line">&nbsp;&nbsp;Writeln(W,&#39; &nbsp; &#39;,ByteAr(W)[1],&#39; &nbsp; &#39;,ByteAr(W)[2]);</div></ol></div></div></div></div><br>
<br>
В результате работы программы будет отпечатано:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">5130 &nbsp; 10 &nbsp; 20</div><div class="code_line">2500 &nbsp; 196 &nbsp; 9</div></ol></div></div></div></div><br>
<br>
B примере <strong class='tag-b'>2</strong> происходит наложение &quot;формального&quot; поля <strong class='tag-b'>ByteAr </strong>длиной два байта на реальное поле <strong class='tag-b'>W</strong>, также имеющее длину два байта. При этом байты, входящие в состав поля <strong class='tag-b'>W</strong>, рассматриваются как отдельные элементы байтового массива типа <strong class='tag-b'>ByteAr</strong>.<br>
Отпечатанные выше элементы в <strong class='tag-b'>16 с/с </strong>имеют следующие значения:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">140A &nbsp; &nbsp; &nbsp;OA &nbsp; &nbsp; 14</div><div class="code_line">09C4 &nbsp; &nbsp; &nbsp;C4 &nbsp; &nbsp; 09</div></ol></div></div></div></div><br>
Cоответствие между элементами полей <strong class='tag-b'>W и ByteAr </strong>легко просматривается, если учесть, что в переменной типа <strong class='tag-b'>word </strong>старшим считается правый байт. Последнее определяется тем, что в процессорах типа <strong class='tag-b'>Intel </strong>числовое значение размещается в поле памяти таким образом, что более старшие разряды числа располагаются в байтах с более старшими адресами. Это положение иллюстрируется ниже на примере переменной <strong class='tag-b'>k типа longint</strong>.<br>
<br>
Переменной <strong class='tag-b'>k</strong> выделяется <strong class='tag-b'>4</strong> байта памяти. Поскольку адресом поля памяти является адрес его крайнего левого байта, то байты поля k получат следующие адреса:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k + 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k + 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;k + 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k + 3</div></ol></div></div></div></div>		<br>
<br>
Пусть  <strong class='tag-b'>k = 2 000 100 101  =  &#036; 77 37 1B 05. </strong>Тогда в байтах с адресами  <strong class='tag-b'>k+0 .. k+3  </strong>шестнадцатеричные цифры значения переменной <strong class='tag-b'>k </strong>будут расположены следующим образом:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">k + 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;k + 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;k + 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k + 3</div><div class="code_line">&nbsp;&nbsp;05 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;37 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 77</div></ol></div></div></div></div><br>
<br>
Приведение типа <strong class='tag-b'>T(v), </strong>где <strong class='tag-b'>T </strong>- имя типа, <strong class='tag-b'>v </strong>- имя переменной, позволяет трактовать на машинном уровне биты, содержащиеся в поле <strong class='tag-b'>v</strong>, как биты, принадлежащие значению типа <strong class='tag-b'>T</strong>. <br>
Пример 3. Определить численные значения байтов, входящих в состав полей памяти типов <strong class='tag-b'>integer </strong>и <strong class='tag-b'>real</strong>. Здесь фактически идет речь об определении внутренного представления переменных типов <strong class='tag-b'>integer и real</strong>.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Program PutType;</div><div class="code_line">Type &nbsp;ByteAr2 = array[1..2] of byte;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ByteAr6 = array[1..6] of byte;</div><div class="code_line">Var &nbsp;I : integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp; R : real;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp; I:=5000; R:=5000;</div><div class="code_line">&nbsp;&nbsp; Writeln(&#39; &nbsp;I: &nbsp;&#39;,ByteAr2(I)[1],&#39; &nbsp;&#39;,ByteAr2(I)[2]);</div><div class="code_line">&nbsp;&nbsp; Writeln(&#39; &nbsp;R: &nbsp;&#39;,ByteAr6(R)[1],&#39; &nbsp;&#39;,ByteAr6(R)[2],</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39; &nbsp;&#39;,ByteAr6(R)[3],&#39; &nbsp;&#39;,ByteAr6(R)[4],</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39; &nbsp;&#39;,ByteAr6(R)[5],&#39; &nbsp;&#39;,ByteAr6(R)[6]);</div><div class="code_line">&nbsp;&nbsp; I:=-5000; R:=-5000;</div><div class="code_line">&nbsp;&nbsp; Writeln(&#39; &nbsp;I: &nbsp;&#39;,ByteAr2(I)[1],&#39; &nbsp;&#39;,ByteAr2(I)[2]);</div><div class="code_line">&nbsp;&nbsp; Writeln(&#39; &nbsp;R: &nbsp;&#39;,ByteAr6(R)[1],&#39; &nbsp;&#39;,ByteAr6(R)[2],</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39; &nbsp;&#39;,ByteAr6(R)[3],&#39; &nbsp;&#39;,ByteAr6(R)[4],</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39; &nbsp;&#39;,ByteAr6(R)[5],&#39; &nbsp;&#39;,ByteAr6(R)[6]);</div><div class="code_line">End.</div></ol></div></div></div></div><br>
<br>
Результаты работы программы удобно представить в следующем виде:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;I: &nbsp;136 &nbsp;19 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;I: &nbsp;88 &nbsp;13</div><div class="code_line">&nbsp;&nbsp;R: &nbsp;141 &nbsp;0 &nbsp; 0 &nbsp; 0 &nbsp; 64 &nbsp; 28 &nbsp; &nbsp; R: &nbsp;8D &nbsp;00 &nbsp;00 &nbsp;00 &nbsp;40 &nbsp;1C</div><div class="code_line">&nbsp;&nbsp;I: &nbsp;120 &nbsp;236 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; I: &nbsp;78 &nbsp;EC</div><div class="code_line">&nbsp;&nbsp;R: &nbsp;141 &nbsp;0 &nbsp; 0 &nbsp; 0 &nbsp; 64 &nbsp;156 &nbsp; &nbsp; R: &nbsp;8D &nbsp;00 &nbsp;00 &nbsp;00 &nbsp;40 &nbsp;9C</div></ol></div></div></div></div><br>
<br>
Здесь в левой части - печатаемые программой результаты (в десятичной системе счисления), в правой части - те же результаты в шестнадцатеричной системе счисления.<br>
<br>
Проверка результатов:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">5000 = 88 ; &nbsp; -5000 = $EC78 ;</div><div class="code_line">1388 = 0,1388 * 164 &nbsp;= 0, 0001 0011 1000 1000 * 2^16 &nbsp;= 0,1001110001000 * 2^13</div></ol></div></div></div></div><br>
<br>
Значение <strong class='tag-b'>R в 16 с/c :  1C 40 00 00 00 8D.</strong><br>
<br>
Полученные результаты четко показывают, что числовые данные располагаются в памяти таким образом, чтобы более старшие разряды находились в байтах с адресами большей величины.<br>
Пусть для вещественной переменной R компилятор отвел поле памяти с адресом <strong class='tag-b'>A</strong>. Так как переменная типа <strong class='tag-b'>real </strong>занимает 6 байтов, то в поле R входят байты с адресами  <strong class='tag-b'>A+0, A+1, A+2, A+3, A+4, A+5</strong>. Тогда для <strong class='tag-b'>R=5000 </strong>байты будут иметь следующее содержимое:<br>
<strong class='tag-b'>(A+0) = 8D ;  (A+1) = 00 ;  (A+2) = 00 ;  (A+3) = 00 ;   (A+4) = 40 ;  (A+5) = 1C .</strong><br>
<br>
Пример 4.<br>
 <br>
<strong class='tag-b'>y = 1, если x &lt; 0 иначе y=0</strong><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Var &nbsp;x : real;</div><div class="code_line">y : byte;</div><div class="code_line">{Вместо условного оператора}</div><div class="code_line">&nbsp;&nbsp; &nbsp;If x&#60;0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;y:=1</div><div class="code_line">&nbsp;&nbsp; &nbsp;Else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;y:=0;</div><div class="code_line">{можно написать}</div><div class="code_line">&nbsp;&nbsp; &nbsp;y:=byte(x&#60;0);</div></ol></div></div></div></div><br>
<br>
<br>
Существует еще несколько способов приведения типов. Один из них это использование<br>
записей с вариантными полями.<br>
<br>
Принцип основан на том, что все вариантные части в записи &quot;накладываются&quot; друг на друга, т.е.<br>
каждому из них выделяется одна и та же область памяти.<br>
<br>
Рассмотрим пример:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;mem4 : record</div><div class="code_line">&nbsp;&nbsp; &nbsp;case byte of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;0 : (by : array[0..3] of byte);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;1 : (wo : array[0..1] of word);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;2 : (lo : longint); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { внимание! case не закрыт операторной скобкой end!}</div><div class="code_line">&nbsp;&nbsp;end;</div></ol></div></div></div></div><br>
<br>
В этом примере запись mem4 имеет три варианта, каждый из которых занимает в памяти один и тот же участок памяти из 4 байт. В зависимости от того, к какому полю записи мы обращаемся, этот участок может рассматриваться как массив из 4 байт (поле by), массив из двух слов (поле wo) или как целое число типа Longint (поле lo). Например этой записи сначала можно присвоить значение как длинному целому, а затем просмотреть результат по байтам или словам:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;x &nbsp;: word;</div><div class="code_line">&nbsp;&nbsp;xb : byte;</div><div class="code_line">&nbsp;&nbsp;xl : longint;</div><div class="code_line">&nbsp;&nbsp;m &nbsp;: mem4;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;with m do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;lo:= trunc(2*pi*x);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if wo[1] = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if by[1] = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xb:= by[0]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x:= wo[0]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xl:= lo</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
Предложение Case... of, открывающее вариантную часть, внешне похоже на соответствующий оператор выбора, но на самом деле играет роль служебного слова, обозначающего начало вариантной части. Именно поэтому в конце вариантной части не стоит END. (Поскольку вариантная часть - всегда последняя в записи, за ней стоит все же стоит END, но он относится к Record). Ключ выбора в предложении Case... of фактически игнорируется компилятором (TP): единственное что нужно учитывать, это то, что ключ выбора должен определять некоторый стандартный или предварительно объявленный порядковый тип.<br>
<br>
Причем этот тип никак не влияет ни на количество вариантных частей, ни на характер констант выбора.<br>
<br>
В стандартном Паскале в качестве ключа выбора необходимо указывать некоторую пременную порядкового типа, причем в исполняемой части программы можно присваивать значение этой переменной и таким образом влиять на выбор полей. В TP также можно в поле ключа выбора указывать переменную порядкового типа и даже присваивать ей значение, что однако не влияет на выбор поля: значение констант выбора в TP могут быть произвольными, в том числе повторяющимися, например:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;rec1 = record</div><div class="code_line">&nbsp;&nbsp;a : byte;</div><div class="code_line">&nbsp;&nbsp;b : eord;</div><div class="code_line">end;</div><div class="code_line">rec2 = record</div><div class="code_line">&nbsp;&nbsp;c: longint;</div><div class="code_line">&nbsp;&nbsp;case x : byte of</div><div class="code_line">&nbsp;&nbsp; &nbsp;1: (d : word);</div><div class="code_line">&nbsp;&nbsp; &nbsp;2: (e : record</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;case boolean of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 : (f : rec1);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 : (g : single);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#39;3&#39;: (c : word)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end)</div><div class="code_line">end;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;r: rec2;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;r.x:=255;</div><div class="code_line">&nbsp;&nbsp;if r.e.g = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;writeln(&#39;OK&#39;)</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;writeln(r.e.g)</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
В этом примере предложение <strong class='tag-b'>case boolean of</strong> в записи, определяемой в поле <strong class='tag-b'>e</strong>, объявляет ключом выбора логический тип, который может иметь всего 2 значения - True или False. Константы же выбора следующих далее вариантов не только содержат не свойственный этому типу значения, но и две из них повторяются, а общее количество вариантов - 3 , а не 2, как следовало бы ожидать.<br>
<br>
Имена полей должны быть уникальными в пределах той записи, где они объявлены, однако, если записи содержат поля-записи, т.е. вложены одна в другую, имена могут повторятся на разных уровнях вложенности (см. поле <strong class='tag-b'>с</strong> в последнем примере).<br>
<br>
Более подоробно узнать о записях и представлении переменных в памяти ЭВМ вы можете в соотвествующих разделах FAQ&#39;а.<br>
<br>
По мотивам лекций Назаренко В.И. и книги Фаронова В.В. &quot;Turbo Pascal 7.0&quot;<br>
<br>
P.S. Существует еще один вариант приведения типов с использованием абсолютных переменных, но об этом я расскажу позже...]]></description>
        <author>e-moe</author>
        <category>Pascal: Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	