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). В этой конструкции, имеющей вид
(имя типа) выражение
Выражение преобразуется к указанному типу по правилам преобразования, изложенным выше. Фактически точный смысл операции перевода можно описать следующим образом: выражение как бы присваивается некоторой переменной указанного типа, которая затем используется вместо всей конструкции. Например, библиотечная процедура SQRT ожидает аргумента типа DOUBLE и выдаст бессмысленный ответ, если к ней по небрежности обратятся с чем-нибудь иным. таким образом, если N целое, то выражение
SQRT((DOUBLE) N) до передачи аргумента функции SQRT преобразует N к типу DOUBLE. (Отметим, что операция перевод преобразует значение N в надлежащий тип; фактическое содержание переменной N при этом не изменяется). Операция перевода имрация перевода имеет тот же уровень старшинства, что и другие унарные операции, как указывается в таблице в конце этой главы.
Упражнение 2-2.
Составьте программу для функции HTOI(S), которая преобразует строку шестнадцатеричных цифр в эквивалентное ей целое значение. При этом допустимыми цифрами являются цифры от 1 до 9 и буквы от а до F.
2.8. Операции увеличения и уменьшения
В языке “C” предусмотрены две необычные операции для увеличения и уменьшения значений переменных. Операция увеличения ++ добавляет 1 к своему операнду, а операция уменьшения—вычитает 1. Мы часто использовали операцию ++ для увеличения переменных, как, например, в
IF(C == 'N') ++I;
Необычный аспект заключается в том, что ++ и—можно использовать либо как префиксные операции (перед переменной, как в ++N), либо как постфиксные (после переменной: N++).
Эффект в обоих случаях состоит в увеличении N. Но выражение ++N увеличивает переменную N до использования ее значения, в то время как N++ увеличивает переменную N после того, как ее значение было использовано. Это означает, что в контексте, где используется значение переменной, а не только эффект увеличения, использование ++N и N++ приводит к разным результатам. Если N = 5, то
х = N++;
устанавливает х равным 5, а х = ++N;
50
полагает х равным 6. В обоих случаях N становится равным 6.
Операции увеличения и уменьшения можно применять только к переменным; выражения типа х=(I+J)++ являются незаконными.
В случаях, где нужен только эффект увеличения, а само значение не используется, как, например, в IF ( C == 'N' ) NL++;
выбор префиксной или постфиксной операции является делом вкуса. но встречаются ситуации, где нужно использовать именно ту или другую операцию. Рассмотрим, например, функцию SQUEEZE(S,C), которая удаляет символ 'с' из строки S, каждый раз, как он встречается.
SQUEEZE(S,C) /* DELETE ALL C FROM S */ CHAR S[];
INT C;
{ INT I, J;
FOR ( I = J = 0; S[I] != ''; I++) IF ( S[I] != C ) S[J++] = S[I];
S[J] = '';
}
Каждый раз, как встечается символ, отличный от 'с', он копируется в текущую позицию J, и только после этого J увеличивается на 1, чтобы быть готовым для поступления следующего символа. Это в точности эквивалентно записи
IF ( S[I] != C ) { S[J] = S[I];
J++;
}
Другой пример подобной конструкции дает функция GETLINE, которую мы запрограммировали в главе 1, где можно заменить IF ( C == 'N' ) { S[I] = C;
++I;
}
более компактной записью IF ( C == 'N' ) S[I++] = C;
В качестве третьего примера рассмотрим функцию STRCAT(S,T), которая приписывает строку т в конец строки S, образуя конкатенацию строк S и т. При этом предполагается, что в S достаточно места для хранения полученной комбинации.
STRCAT(S,T) /* CONCATENATE T TO END OF S */ CHAR S[], T[]; /* S MUST BE BIG ENOUGH */
{ INT I, J;
I = J = 0;
WHILE (S[I] != '') / *FIND END OF S */ I++;
WHILE((S[I++] = T[J++]) != '') /*COPY T*/
;
}
Tак как из T в S копируется каждый символ, то для подготовки к следующему прохождению цикла постфиксная операция ++ применяется к обеим переменным I и J.
Упражнение 2-3.
Напишите другой вариант функции SQUEEZE(S1,S2), который удаляет из строки S1 каждый символ, совпадающий с каким-либо символом строки S2.
Упражнение 2-4.
Напишите программу для функции ANY(S1,S2), которая находит место первого появления в строке S1 какого-либо символа из строки S2 и, если строка S1 не содержит символов строки S2, возвращает значение -1.
... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...
... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...
... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...
... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...
0 комментариев