Дополнительные операции языка
Мы уже упоминали о
компактности языка Си, столь ценимой в системном
программировании. Этому способствует и ряд
вспомагатетельных операции. Вот список основных
операций языка:
+, & , \ ,
^ , |
?: , --, /, ++,
>
>=, ++, !=, << , <
<=, &&, !, ||, %
~, >>, -> , - , =, *
Операции
уменьшения и увеличения.
В языке
Си широко используются две нетрадиционные
операции для увелечения и уменьшения значения
переменной, обозначенные соответственно ++ и -- .
Операция ++ прибавляет единицу к операнду, а --
вычитает.Эти операции могут быть использованны и
перед, и после своего операнда. Они оказывают
разные действия в выражениях: в записи ++n
увеличение происходит до использования значения
n, а в n++ увеличение идет уже после того, как
используется значение n. Если считать, что
значение n равно 5, то переменная m в выражении m=++n
,будет иметь значение 6, а в выражение m=n++
переменная m равна 5, в том и этом случае
переменная n будет равняться 6. Первый пример в
точности соответствует следующей
последовательности операторов n=n+1; m=n; а второй
последовательности m=n; n=n+1; Операция действует
аналагично.Обе операции имеют самый низкий
приоритет и выполняются после бинарных операций
+ и -. Рассмотрим пример 3.1 .
Пример 3.1
/*определить двузначные целые
числа,
которые делятся на сумму своих цифр*/
#include <stdio.h>
main()
{
int a,b,k,s,c;
k=0;a=1;
while(a<=9)
{
b=0;
while(b<=9)
{
s=a+b;
c=a*10+b;
if(c%s==0)
{
printf("%d",c);
k++;
}
b++;
}
a++; printf("\n");
}
printf("всего: %d\n", k);
} |
Поразрядные логические операции предназначенные
для работы с отдельными битами целого числа или
символа.
&
- поразрядное И
^ - поразрядное исключающее ИЛИ
>> - сдвиг вправо
| - поразрядное ИЛИ
<< - сдвиг в лево
~ - инверсия |
Поразрядная
операция И (&) часто используется для
выделения некотрой группы двоичных разрядов,
напрмер n=n&0177 устанвливает в нуль
все двоичные разряды числа n, кроме семи младших.
Операция ИЛИ( | ) используется для
установки отдельных разрядов в единицу. Напрмер.
m=m |
0xF0F; "включает" 11,10, 9,8,3,2,1 и 0 разряды
числа m. Операции << и >> выполняют сдвиг
операдна влево или вправо на заданное число
разрядов. Напрмер, m<<3 сдигает
значение m на 3 разряда влево, заполняя
освобождающиеся младшие разряды нулями. Унарная
операция ~ выполняет инверсию двоичных
разрядов числа(символа), т.е. преобразует каждый
единичный бит в нулевой и наоборот. Применение
некоторых поразрядных операций покажем на
примерах. В программе на прмере 3.2 исходное число
511 дано в шестнадцатиричной форме: m= 0X|FF; Напомним,
что написанная перед константой число 0
указывает на восьмеричное число, а 0X на
шестнадцатиричное. Для выода результата
предусмотрена функция PRINT. Она для
удобства анализа результатов печатает числа в
шестнадцатиричном, восьмеричном и десятиричном
форматах, используя для этого спецификацию
x, o ,d. Остальные действия в программе
коментируются и дополнительных пояснений не
надо.
Пример 3.2
/*поразрядные логические операции*/
#include <stdio.h >
PRINT(n)
int n;
{
printf("%5x %5o %5d \n",n,n,n);
}
main()
{
int m,n;
m=0X1F3; PRINT(m); /*16- ричное число*/
n=m&0177 PRINT(n); /* выделение 7 мл.бит*/
n=m|013; PRINT(n); /*установка 4 мл.бит*/
n=m>>4 ; PRINT(n); /*сдвиг вправо*/
m=n<<3 ; PRINT(m); /*сдвиг влево*/
}
|
Следующяя программа (прмер 3.3), используя команду
сдвига числа вправо на один бит (m=n>>1;)
и выделения младшего разряда числа (m&01),
подсчитывает кол-во единичных битов исходного
числа и печатает результат.
Пример 3.3
/* подсчет единиц */
#include <stdio.h>
main()
{
int m,k;
k=0;
m=0xf0f;
while(m!=0)
{
if(m&01)k++;
m=m>>1;
}
printf("k=%d\n",k);
}
|
Операции присваивания и выражения.
Выражение вида i=i+b, где левая часть
повторяется в правой части, могут быть заменены в
сжатой форме: i+ =b. При этом используется
операция присваивания вида +=, которая означает
буквально "увеличить i на b". Для
большинства бинарных операций допускается
запись вида op=, где op - одна из
операций: + - / % | ^ & <<>>. Если E1op=E2
эквивалентно E1=(E1)op(E2). Обратите внимание
на скобки вокруг E2; присвание x*=y+1 фактически
означает x=x*(y+1), а не x=x*y+1. В
качестве иллюстраций, поясняющей сказанное,
рассмотрим программу (пример 3.4), в которой по
заданному натуральному числу n строится
число m, написанное теми же цифрами, что
и n, но взятыми в обратном порядке. Правду говоря,
запись m=m*10+z более прозрачна, чем
непривычная последовательность m*=10; m+=z.
Пример 3.4
#include stdio.h
main()
{
int n,z,m=0;
printf("введи n n\");
scanf("%d",&n);
while(n!=0)
{
z=n%10;
n/=10;
m*=10;
m+=z
}
printf("m=%d\n",m);
}
|
Условная
операция. Фактически она представляет собой
сокращенную форму оператора if - then - else, и
в общем виде записывается так: выражение1?
выражение2? выражение3?. Если
"выражение1" не равно нулю, то результатом
операции будет значение "выражение2", в
противном случае - значение "выражение3" .
Условная операция, называемая иногда тенарной,
определяет обычное выражение. которое может. в
частности, быть использовано в операторе
присваивания. Таким образом, вместо if(x >
y) max=c; else max=y; достаточно написать: max=(x>y)&
x:y. Скобки вокруг "выражения1" ставить
не обязательно, так как приоритет операции :? очень
низкий, ниже он только у присваивания. Условная
операция позволяет писать долее короткие
программы. Вот как выглядит в программе (пример
3.5) цикл для печати квадратов натуральныз чисел
от 1 до m, по 6 чисел в строке; каждое число занимает
5 позиций и колонки отделяются одним пробелом, а
каждая строка, включая последнюю, заканчивается
символом перевода на новую строку
"печатается" после каждого шестого элемента
и после m-го. За любыми другими элементами
выводится один пробел.
Пример 3.5
/*квадраты натуральных чисел*/
main()
{
int m,i=1;scanf("%d",&m);
while(i_=m)
{
printf("5%d%c",i*i,(i%6==0 || i==m)? '\n':' ');
i++;
}
}
|
< Дальше >
|