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] != '\0'; I++)
IF ( S[I] != C )
S[J++] = S[I];
S[J] = '\0';
}
Каждый раз, как встечается символ, отличный от 'с', он копи-
руется в текущую позицию 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;
· 51 -
В качестве третьего примера рассмотрим функцию
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] != '\0') / *FIND END OF S */
I++;
WHILE((S[I++] = T[J++]) != '\0') /*COPY T*/
;
}
Tак как из T в S копируется каждый символ, то для подготовки
к следующему прохождению цикла постфиксная операция ++ при-
меняется к обеим переменным I и J.
Упражнение 2-3.
Напишите другой вариант функции SQUEEZE(S1,S2), который
удаляет из строки S1 каждый символ, совпадающий с каким-либо
символом строки S2.
Упражнение 2-4.
Напишите программу для функции ANY(S1,S2), которая нахо-
дит место первого появления в строке S1 какого-либо символа
из строки S2 и, если строка S1 не содержит символов строки
S2, возвращает значение -1.
2.9. Побитовые логические операции
В языке предусмотрен ряд операций для работы с битами;
эти операции нельзя применять к переменным типа FLOAT или
DOUBLE.
& Побитовое AND
\! Побитовое включающее OR
^ побитовое исключающее OR
<< сдвиг влево
>> сдвиг вправо
\^ дополнение (унарная операция)
“\” иммитирует вертикальную черту.
Побитовая операция AND часто используется для маскирования
некоторого множества битов; например, оператор
C = N & 0177
· 52 -
передает в 'с' семь младших битов N , полагая остальные рав-
ными нулю. Операция 'э' побитового OR используется для вклю-
чения битов:
C = X э MASK
устанавливает на единицу те биты в х , которые равны единице
в MASK.
Следует быть внимательным и отличать побитовые операции
& и 'э' от логических связок && и \!\! , Которые подразуме-
вают вычисление значения истинности слева направо. Например,
если х=1, а Y=2, то значение х&Y равно нулю , в то время как
значение X&&Y равно единице./почему?/
Операции сдвига << и >> осуществляют соответственно
сдвиг влево и вправо своего левого операнда на число битовых
позиций, задаваемых правым операндом. Таким образом , х<<2
сдвигает х влево на две позиции, заполняя освобождающиеся
биты нулями, что эквивалентно умножению на 4. Сдвиг вправо
величины без знака заполняет освобождающиеся биты на некото-
рых машинах, таких как PDP-11, заполняются содержанием зна-
кового бита /”арифметический сдвиг”/, а на других - нулем
/”логический сдвиг”/.
Унарная операция \^ дает дополнение к целому; это озна-
чает , что каждый бит со значением 1 получает значение 0 и
наоборот. Эта операция обычно оказывается полезной в выраже-
ниях типа
X & \^077
где последние шесть битов х маскируются нулем. Подчеркнем,
что выражение X&\^077 не зависит от длины слова и поэтому
предпочтительнее, чем, например, X&0177700, где предполага-
ется, что х занимает 16 битов. Такая переносимая форма не
требует никаких дополнительных затрат, поскольку \^077 явля-
ется константным выражением и, следовательно, обрабатывается
во время компиляции.
Чтобы проиллюстрировать использование некоторых операций
с битами, рассмотрим функцию GETBITS(X,P,N), которая возвра-
щает /сдвинутыми к правому краю/ начинающиеся с позиции р
поле переменной х длиной N битов. мы предполагаем , что
крайний правый бит имеет номер 0, и что N и р - разумно за-
данные положительные числа. например, GETBITS(х,4,3) возвра-
щает сдвинутыми к правому краю биты, занимающие позиции 4,3
и 2.
GETBITS(X,P,N) /* GET N BITS FROM POSITION P */
UNSIGNED X, P, N;
{
RETURN((X >> (P+1-N)) & \^(\^0 << N));
}
· 53 -
Операция X >> (P+1-N) сдвигает желаемое поле в правый конец
слова. Описание аргумента X как UNSIGNED гарантирует, что
при сдвиге вправо освобождающиеся биты будут заполняться ну-
лями, а не содержимым знакового бита, независимо от того, на
какой машине пропускается программа. Все биты константного
выражения \^0 равны 1; сдвиг его на N позиций влево с по-
мощью операции \^0<<N создает маску с нулями в N крайних
правых битах и единицами в остальных; дополнение \^ создает
маску с единицами в N крайних правых битах.
Упражнение 2-5.
Переделайте GETBITS таким образом, чтобы биты отсчитыва-
лись слева направо.
Упражнение 2-6.
Напишите программу для функции WORDLENGTH(), вычисляющей
длину слова используемой машины, т.е. Число битов в перемен-
ной типа INT. Функция должна быть переносимой, т.е. Одна и
та же исходная программа должна правильно работать на любой
машине.
Упражнение 2-7.
Напишите программу для функции RIGHTROT(N,B), сдвигающей
циклически целое N вправо на B битовых позиций.
Упражнение 2-8.
Напишите программу для функции INVERT(X,P,N), которая
инвертирует (т.е. Заменяет 1 на 0 и наоборот) N битов X, на-
чинающихся с позиции P, оставляя другие биты неизмененными.
... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...
... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...
... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...
... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...
0 комментариев