Преобразование типов

Язык С
Строк программы, исключая математическое обеспечение Является учебным введением в центральную часть языка “C” Hачинаем. Единственный способ освоить новый язык Оператор FOR Набор полезных программ Подсчет символов Подсчет слов Функции Аргументы - вызов по значению Область действия: внешние переменные Резюме Константы Описания Преобразование типов До 9 и буквы от а до F Операции и выражения присваивания Старшинство и порядок вычисления Операторы и блоки Переключатель Цикл DO - WHILE Оператор CONTINUE Основные сведения Функции, возвращающие нецелые значения Еще об аргументах функций Правила, определяющие область действия Статические переменные Блочная структура Рекурсия Указатели и адреса Указатели и массивы Адресная арифметика Указатели символов и функции Указатели - не целые До 12, а не от 0 до 11. Так как за экономию памяти у нас пока не награждают, такой способ проще, чем подгонка индек-сов Инициализация массивов указателей Указатели на функции Структуры Структуры и функции Указатели на структуры Мы продемонстрируем, как правильно выполнить эту задачу Поля Определение типа Обращение к стандартной библиотеке Форматный вывод - функция PRINTF Форматный ввод - функция SCANF Форматное преобразование в памяти Обработка ошибок - STDERR и EXIT Обращение к системе Низкоуровневый ввод/вывод - операторы READ и WRITE Произвольный доступ - SEEK и LSEEK Пример - распечатка справочников Пример - распределитель памяти Константы Синтаксическая нотация Преобразования Первичные выражения Унарные операции Аддитивные операции Операция присваивания Спецификаторы типа Описание структур и объединений Инициализация TYPEDEF Оператор SWITCH Внешнее определение функции Область действия внешних идентификаторов Неявные описания Явные преобразования указателей Анахронизмы Операторы
439386
знаков
0
таблиц
0
изображений

2.7. Преобразование типов

Если в выражениях встречаются операнды различных типов,

то они преобразуются к общему типу в соответствии с неболь-

шим набором правил. В общем, автоматически производятся

только преобразования, имеющие смысл, такие как, например,

преобразование целого в плавающее в выражениях типа F+I. Вы-

ражения же, лишенные смысла, такие как использование пере-

менной типа FLOAT в качестве индекса, запрещены.

Во-первых, типы CHAR и INT могут свободно смешиваться в

арифметических выражениях: каждая переменная типа CHAR авто-

матически преобразуется в INT. Это обеспечивает значительную

гибкость при проведении определенных преобразований симво-

лов. Примером может служить функция ATOI, которая ставит в

соответствие строке цифр ее численный эквивалент.

 


·     46 -

ATOI(S) /* CONVERT S TO INTEGER */

CHAR S[];

{

INT I, N;

N = 0;

FOR ( I = 0; S[I]>='0' && S[I]<='9'; ++I)

N = 10 * N + S[I] - '0';

RETURN(N);

}

 

KAK Уже обсуждалось в главе 1, выражение

S[I] - '0'

имеет численное значение находящегося в S[I] символа, потому

что значение символов '0', '1' и т.д. образуют возрастающую

последовательность расположенных подряд целых положительных

чисел.

Другой пример преобразования CHAR в INT дает функция

LOWER, преобразующая данную прописную букву в строчную. Если

выступающий в качестве аргумента символ не является пропис-

ной буквой, то LOWER возвращает его неизменным. Приводимая

ниже программа справедлива только для набора символов ASCII.

 

LOWER© /* CONVERT C TO LOWER CASE; ASCII ONLY */

INT C;

 {

IF ( C >= 'A' && C <= 'Z' )

RETURN( C + '@' - 'A');

ELSE /*@ Записано вместо 'A' строчного*/

RETURN©;

 }

 

Эта функция правильно работает при коде ASCII, потому что

численные значения, соответствующие в этом коде прописным и

строчным буквам, отличаются на постоянную величину, а каждый

алфавит является сплошным - между а и Z нет ничего, кроме

букв. Это последнее замечание для набора символов EBCDIC

систем IBM 360/370 оказывается несправедливым, в силу чего

эта программа на таких системах работает неправильно - она

преобразует не только буквы.

При преобразовании символьных переменных в целые возни-

кает один тонкий момент. Дело в том, что сам язык не указы-

вает, должны ли переменным типа CHAR соответствовать числен-

ные значения со знаком или без знака. Может ли при преобра-

зовании CHAR в INT получиться отрицательное целое? К сожале-

нию, ответ на этот вопрос меняется от машины к машине, отра-

жая расхождения в их архитектуре. На некоторых машинах

(PDP-11, например) переменная типа CHAR, крайний левый бит

которой содержит 1, преобразуется в отрицательное целое

(“знаковое расширение”). На других машинах такое преобразо-

вание сопровождается добавлением нулей с левого края, в ре-

зультате чего всегда получается положительное число.


·     47 -

Определение языка “C” гарантирует, что любой символ из

стандартного набора символов машины никогда не даст отрица-

тельного числа, так что эти символы можно свободно использо-

вать в выражениях как положительные величины. Но произволь-

ные комбинации двоичных знаков, хранящиеся как символьные

переменные на некоторых машинах, могут дать отрицательные

значения, а на других положительные.

Наиболее типичным примером возникновения такой ситуации

является сучай, когда значение 1 используется в качестве

EOF. Рассмотрим программу

 

CHAR C;

C = GETCHAR();

IF ( C == EOF )

...

На машине, которая не осуществляет знакового расширения,

переменная 'с' всегда положительна, поскольку она описана

как CHAR, а так как EOF отрицательно, то условие никогда не

выполняется. Чтобы избежать такой ситуации, мы всегда пре-

дусмотрительно использовали INT вместо CHAR для любой пере-

менной, получающей значение от GETCHAR.

Основная же причина использования INT вместо CHAR не

связана с каким-либо вопросом о возможном знаковом расшире-

нии. просто функция GETCHAR должна передавать все возможные

символы (чтобы ее можно было использовать для произвольного

ввода) и, кроме того, отличающееся значение EOF. Следова-

тельно значение EOF не может быть представлено как CHAR, а

должно храниться как INT.

Другой полезной формой автоматического преобразования

типов является то, что выражения отношения, подобные I>J, и

логические выражения, связанные операциями && и \!\!, по оп-

ределению имеют значение 1, если они истинны, и 0, если они

ложны. Таким образом, присваивание

 

ISDIGIT = C >= '0' && C <= '9';

полагает ISDIGIT равным 1, если с - цифра, и равным 0 в про-

тивном случае. (В проверочной части операторов IF, WHILE,

FOR и т.д. “Истинно” просто означает “не нуль”).

Неявные арифметические преобразования работают в основ-

ном, как и ожидается. В общих чертах, если операция типа +

или *, которая связывает два операнда (бинарная операция),

имеет операнды разных типов, то перед выполнением операции

“низший” тип преобразуется к “высшему” и получается резуль-

тат “высшего” типа. Более точно, к каждой арифметической

операции применяется следующая последовательность правил

преобразования.

·     Типы CHAR и SHORT преобразуются в INT, а FLOAT в

DOUBLE.

·      
48 -

·     Затем, если один из операндов имеет тип DOUBLE, то

другой преобразуется в DOUBLE, и результат имеет тип DOUBLE.

·     В противном случае, если один из операндов имеет тип LONG, то другой преобразуется в LONG, и результат имеет тип LONG.

·     В противном случае, если один из операндов имеет тип UNSIGNED, то другой преобразуется в UNSIGNED и результат имеет тип UNSIGNED.

·     В противном случае операнды должны быть типа INT, и

результат имеет тип INT.

Подчеркнем, что все переменные типа FLOAT в выражениях пре-

образуются в DOUBLE; в “C” вся плавающая арифметика выполня-

ется с двойной точностью.

Преобразования возникают и при присваиваниях; значение

правой части преобразуется к типу левой, который и является

типом результата. Символьные переменные преобразуются в це-

лые либо со знаковым расширением ,либо без него, как описано

выше. Обратное преобразование INT в CHAR ведет себя хорошо -

лишние биты высокого порядка просто отбрасываются. Таким об-

разом

 

INT I;

CHAR C;

I = C;

C = I;

значение 'с' не изменяется. Это верно независимо от того,

вовлекается ли знаковое расширение или нет.

Если х типа FLOAT, а I типа INT, то как

х = I;

так и

I = х;

 

приводят к преобразованиям; при этом FLOAT преобразуется в

INT отбрасыванием дробной части. Тип DOUBLE преобразуется во

FLOAT округлением. Длинные целые преобразуются в более ко-

роткие целые и в переменные типа CHAR посредством отбрасыва-

ния лишних битов высокого порядка.

Так как аргумент функции является выражением, то при пе-

редаче функциям аргументов также происходит преобразование

типов: в частности, CHAR и SHORT становятся INT, а FLOAT

становится DOUBLE. Именно поэтому мы описывали аргументы

функций как INT и DOUBLE даже тогда, когда обращались к ним

с переменными типа CHAR и FLOAT.

Наконец, в любом выражении может быть осуществлено

(“принуждено”) явное преобразование типа с помощью конструк-

ции, называемой перевод (CAST). В этой конструкции, имеющей

вид

 

(имя типа) выражение


·     49 -

Выражение преобразуется к указанному типу по правилам

преобразования, изложенным выше. Фактически точный смысл

операции перевода можно описать следующим образом: выражение

как бы присваивается некоторой переменной указанного типа,

которая затем используется вместо всей конструкции. Напри-

мер, библиотечная процедура SQRT ожидает аргумента типа

DOUBLE и выдаст бессмысленный ответ, если к ней по небреж-

ности обратятся с чем-нибудь иным. таким образом, если N -

целое, то выражение

 

SQRT((DOUBLE) N)

до передачи аргумента функции SQRT преобразует N к типу

DOUBLE. (Отметим, что операция перевод преобразует значение

N в надлежащий тип; фактическое содержание переменной N при

этом не изменяется). Операция перевода имрация перевода име-

ет тот же уровень старшинства, что и другие унарные опера-

ции, как указывается в таблице в конце этой главы.

Упражнение 2-2.

Составьте программу для функции HTOI(S), которая преоб-

разует строку шестнадцатеричных цифр в эквивалентное ей це-

лое значение. При этом допустимыми цифрами являются цифры от


Информация о работе «Язык С»
Раздел: Информатика, программирование
Количество знаков с пробелами: 439386
Количество таблиц: 0
Количество изображений: 0

Похожие работы

Скачать
48443
0
0

... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...

Скачать
43709
0
0

... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...

Скачать
39778
0
1

... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...

Скачать
64931
0
0

... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...

0 комментариев


Наверх