Арифметические и поразрядные операции в языке Си. Сокращенная форма записи операций. Условные выражения.

Над целочисленными данными (константами и переменными) в языках C, C++ можно выполнять обычные арифметические операции – сложение (x+y), вычитание (z-5), умножение (x1*x3) и деление (y/w). В отличие от языка Pascal здесь деление целочисленных операндов дает целочисленный результат. Например, 5/2=2. Для получения остатка от деления в C, C++ используется операция %, например, 5%2=1.

Целочисленные данные можно подвергать операции сдвига как влево (знак операции – <<), так и вправо (знак операции – >>) на заданное количество двоичных разрядов:

y=x<<3; // сдвиг влево на три двоичные разряда

z=y>>5; // сдвиг вправо на пять двоичных разрядов

Операция сдвига вправо работает по-разному для целых чисел со знаком и целых чисел без знака. Внимательно посмотрите на результат работы следующей программы:

#include <stdio.h>

#include <conio.h>

int main()

{

int x=5, y=-5;

unsigned z=0xFFFFFFFB;

printf("x=%x y=%x z=%x",x,y,z);

printf("\nx<<2=%x x>>2=%x",x<<2,x>>2);

printf("\ny<<2=%x y>>2=%x",y<<2,y>>2);

printf("\nz<<2=%x z>>2=%x",z<<2,z>>2);

getch();

return 0;

}

//=== Результат работы ===

x=5 y=fffffffb z=fffffffb

x<<2=14 x>>2=1

y<<2=ffffffec y>>2=fffffffe

z<<2=ffffffec z>>2=3ffffffe

Дело в том, что для чисел со знаком операция сдвига на n разрядов эквивалентна умножению на 2n при сдвиге влево или делению на 2n при сдвиге вправо. Поэтому для отрицательного операнда результат сдвига должен остаться отрицательным. С этой целью при сдвиге вправо производится размножение знакового разряда.

Над одноименными двоичными разрядами целочисленных операндов могут выполняться логические операции – логическое сложение (символ операции '|'), логическое умножение (символ операции '&'), исключающее ИЛИ (символ операции '^') и инвертирование (символ операции '~'). Приведенная ниже программа иллюстрирует выполнение указанных операций над переменными x=5 (двоичный код 00…0101) и y=7 (двоичный код 00…0111).

#include <stdio.h>

#include <conio.h>

int main()

{

int x=5, y=7;

printf("x=%x y=%x",x,y);

printf("\nx|y=%x x&y=%x",x|y,x&y);

printf("\nx^y=%x ~x=%x",x^y,~x);

getch();

return 0;

}

//=== Результат работы ===

x=5 y=7

x|y=7 x&y=5

x^y=2 ~x=fffffffa

Специальные формы оператора присваивания

Следующая группа операторов присваивания обязана своим происхождением формату машинных команд в двухадресных машинах:

COD A1,A2

Здесь COD – код машинной операции;

A1,A2 – адреса ячеек оперативной памяти и/или арифметических регистров.

Результат выполнения такой операции над содержимым A1 и A2 записывается по адресу A1 (A1=A1ÄA2). По аналогии с такой записью в языках C, C++ появилась следующая синтаксическая конструкция:

v Ä= exp; //вместо v = v Ä exp;

Здесь символ Ä обозначает один из следующих знаков двухместных операций:

+,-,*,/,%,<<,>>,&,|,^

Например:

x += 2; //вместо x=x+2;

z /= 1.5; //вместо z=z/1.5;

Довольно экзотически выглядит оператор присваивания, в правой части которого через запятую задана последовательность некоторых действий. Например:

x=(y=sin(a+b),z=cos(a-b),max(y,z));

Действия в скобках выполняются слева направо, т.е. сначала будет вычислено значение sin(a+b), которое занесут в переменную y, затем будет вычислено значение переменной z. Окончательным результатом скобки, которое будет присвоено переменной x, станет вычисление значения функции max(y,z).

Условный оператор

С помощью условного оператора в программе можно создать две альтернативные цепочки операторов, выполнение каждой из которых происходит в зависимости от истинности или ложности заданного условия:

if(условие) {S1; S2;...} [else {Q1;Q2;...}]

Если условие, указанное в круглых скобках истинно, то выполняется цепочка операторов S1, S2,… . В противном случае выполняется цепочка операторов Q1,Q2,… . Альтернативная ветвь вместе со служебным словом else может отсутствовать. И тогда речь идет о выполнении или обходе цепочки операторов S1,S2,… .

Простейшие условия задаются в виде проверки соотношения двух однотипных выражений:

if(a>b) cout<<a; else cout<<b;

if(x>=0) y=sqrt(x);

Напомним, что операции отношения в языках C, C++ обозначаются следующими символами и их комбинациями:

== равно != не равно > больше
>= больше или равно < меньше <= меньше или равно

Более сложные условия могут составляться из элементарных соотношений с помощью логических операций "ИЛИ" (||), "И" (&&), "НЕ" (!). Например, проверка принадлежности x диапазону [a,b] выглядит следующим образом:

if(a<=x && x<=b) ...

В качестве логического условия иногда можно встретить в круглых скобках обычное арифметическое выражение:

if(a)...

В языке C логические переменные отсутствуют. Вместо этого действует соглашение о том, что ложь эквивалентна нулевому значению числового выражения, а истина – не нулевому значению. Поэтому приведенная выше проверка эквивалентна соотношению:

if(a != 0)...

Наши рекомендации