Материал: lectures_3

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

18.1.Логические операторы

Логические операторы используются для повышения выразительных средств языка. В языке Си имеются три логических оператора:

! – логическое НЕ,

&& - логическое И,

|| - логическое ИЛИ.

Оператор ! является унарным оператором, а операторы && и || - бинарными. В качестве операндов логических операторов могут использоваться арифметические выражения, отношения и сравнения на равенство. Логические операции задаются с помощью так называемых таблиц истинности. Предположим, что имеются две логические величины a, b. Тогда таблицы истинности для рассматриваемых операторов можно представить в следующем виде:

ab Логическая операция

false

false

!a

!b

a && b

a || b

true

true

false

false

false

true

true

false

false

true

true

false

false

true

false

true

true

true

false

false

true

true

Значение результата выполнения оператора ! является обратным по отношению к его операнду. Значение, полученное в результате выполнения оператора &&, истинно только в том случае, когда истинны его оба операнда. Значение результата выполнения оператора || истинно в том случае, когда истинен хотя бы один операнд. Отметим, что бинарные операторы относятся к немногочисленной категории операторов, для которых фиксирован порядок вычисления операндов. Этот порядок выполнения состоит в следующем. Вначале всегда вычисляется левый операнд. Если после его вычисления значение выражения становится очевидным, то правый операнд не вычисляется. Например, если при вычислении выражения, содержащего оператор &&, значение левого операнда оказалось равным false, то из этого заведомо следует, что значением всего выражения будет логическое значение false. При этом необходимость в вычислении правого операнда отпадает.

18.2.Поразрядные операторы

Эти операторы могут быть полезными в тех случаях, когда программисту требуется непосредственно взаимодействовать с аппаратурными компонентами компьютера. В языке Си имеется шесть поразрядных операторов:

~ поразрядное НЕ,

& поразрядное И,

| поразрядное ИЛИ,

^ поразрядное ИСКЛЮЧАЮЩЕЕ ИЛИ,

<< сдвиг влево,

>> сдвиг вправо.

41

Отметим, что поразрядные операторы применимы только к целочисленным операндам.

Краткое описание поразрядных операторов содержится в таблице, приведенной ниже.

Оператор

Название

Описание

операнда,

равные

0,

~

Поразрядное НЕ

Все

биты

 

 

устанавливаются в 1, а все

биты,

 

 

значения

которых

равны

 

1,

 

 

устанавливаются в 0.

 

 

 

&Поразрядное И Бит результата устанавливается в 1

 

 

только

в

том

 

случае,

когда

 

 

соответствующие

биты

обоих

операндов

 

 

установлены в 1, во всех других

 

 

случаях

этот

бит

устанавливается

в

|

Поразрядное ИЛИ

0.

результата

устанавливается в 1

в

Бит

 

 

том случае, когда хотя бы один из

 

 

соответствующих

и

битов

операндов

 

 

установлен в

1

устанавливается

в

 

 

0, если оба соответствующих бита,

^

Поразрядное

установлены в 0.

 

 

 

 

1,

Бит

результата

устанавливается в

 

ИСКЛЮЧАЮЩЕЕ ИЛИ

если

соответствующий

бит

одного

и

 

 

только одного операнда установлен в

 

 

1, во всех других случаях этот бит

<<

Сдвиг влево

устанавливается в 0.

левого

операнда

Сдвигает

влево

биты

 

 

на

количество

 

позиций,

 

которое

 

 

определяется

 

правым

операндом.

 

 

Правые

освобождающиеся

 

позиции

>>

Сдвиг вправо

заполняются нулями.

левого

операнда

Сдвигает

вправо

биты

 

 

на

количество

 

позиций,

 

которое

 

 

определяется

 

правым

операндом.

 

 

Способ

заполнения

освобождающихся

 

 

позиций

является

аппаратно

 

 

зависимым.

 

 

 

 

 

 

 

Пусть имеется следующий фрагмент программы, содержащий

выражения, использующие поразрядные операции.

/* .....................*/ unsigned char n = 0x2A; unsigned char m = 0x71; unsigned char r;

r = ~n;

printf("~n = %X\n", r);

r = ~m;

printf("~m = %X\n", r);

42

r = n & m;

printf("n & m = %X\n", r);

r = n | m;

printf("n | m = %X\n", r);

r = n << 2;

= %X\n",

r);

printf("n << 2

r = m >> 1;

= %X\n",

r);

printf("m >> 1

/* ........................

 

*/

Результаты выполнения этого фрагмента программы имели следующий

вид:

~n = D5 ~m = 8E

n & m = 20 n | m = 7B n << 2 = A8 m >> 1 = 38

19. Условные выражения (оператор ?:)

Условные выражения записываются с помощью тернарного оператора ?:.

Этот оператор имеет следующий формат:

выр1 ? выр2 : выр3

Здесь выр1, выр2 и выр3 – выражения.

Условное выражение вычисляется следующим образом. Вначале оценивается булевское значение выражения выр1. Если его значением является true, то дальше вычисляется значение выражения выр2 и значение этого выражения становится значением всего условного выражения, в противном случае вычисляется значение выражения выр3 и его значение становится значением всего условного выражения.

В качестве примера применения условного выражения рассмотрим задачу о нахождении наибольшего значения двух вещественных чисел a и b. Ниже приведена программа, предназначенная для решения этой задачи.

/* Файл max.c */ #include<stdio.h>

int main(void)

{

double a, b; printf(“a=”); scanf(“%lf”, &a); printf(“b=”); scanf(“%lf”, &b);

printf(“max=%8.3f\n”, (a > b ? a : b)); return 0;

}

43

Здесь использовалось то обстоятельство, что условное выражение действительно является выражением, и оно может быть использовано в качестве аргумента в вызове функции printf().

20. Оператор запятая

Это бинарный оператор, имеющий следующий формат:

выр1 , выр2

Здесь выр1 и выр2 – выражения. Вначале вычисляется левый операнд. Значение этого операнда после его вычисления отбрасывается (исключается из рассмотрения). Затем вычисляется правый операнд. Вычисленное значение этого операнда становятся типом и значением всего выражения в целом. В месте, где расположена запятая, находится точка следования (sequence point). Это означает, что до перехода к вычислению выражения выр2 все побочные эффекты, которые могут иметь место при вычислении выражения выр1 должны быть завершены. Оператор запятая в основном применяется в инструкции for в ее первом и третьем выражениях (см. 1.29).

21. Оператор sizeof

Этот оператор в качестве своего результата возвращает размер памяти, занимаемый его операндом. Оператор используется в двух формах:

sizeof(type)

sizeof expr

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

Приведем примеры использования рассматриваемого оператора:

printf(“sizeof 2 = %d\n”, sizeof 2); printf(“sizeof(double) = %d\n”, sizeof(double));

22. Инструкции перехода

Инструкции перехода приводят к безусловной передаче управления в другую точку программы. К этой категории инструкций в языке Си относятся следующие инструкции:

break,

continue,

goto,

return.

22.1.Инструкция break

Эта инструкция используется только в теле инструкций for, while, do … while и switch. Ее назначение состоит в завершении выполнения инструкций, внутри которых она расположена. При использовании инструкции break во вложенных циклах завершит свою работу только текущий цикл. После этого управление передается циклу, находящемуся “на один уровень выше”.

44

22.2.Инструкция continue

Эта инструкция используется только в теле циклических инструкций for, while и dowhile. Ее выполнение приводит к завершению очередного шага цикла.

22.3.Инструкция goto

Выполнение этой инструкции состоит в прерывании естественного порядка выполнения программы и безусловной передаче управления. Рассматриваемая инструкция состоит из двух частей: зарезервированного слова goto и имени метки. В качестве имени метки используется идентификатор. Пример инструкции goto:

goto error;

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

инструкции:

error : printf(“Ошибка ввода \n”);

22.4.Инструкция return

Эта инструкция возвращает управление в вызывающую функцию. Если функция должна иметь возвращаемое значение, то в теле должна

встретиться инструкция return, имеющая следующий формат: return [выр];

Рассматриваемая инструкция состоит из двух структурных частей: зарезервированного слова return и необязательного выражения выр. Необходимость в выражении выр отсутствует в том случае, когда функция не возвращает значение. В качестве примера приведем определение функции, предназначенной для определения максимального значения двух чисел.

double max(double a, double b)

{

return ((a > b) ? a : b);

}

В теле рассматриваемой функции max() находится только одна инструкция – инструкция return. Эта инструкция выполняет два действия. Во-первых, инструкция формирует с помощью условного выражения возвращаемый результат. Во-вторых, она прекращает вычисления в функции max() и передает управление в точку вызова функции.

23. Составная инструкция

Составная инструкция – это последовательность объявлений, определений и инструкций, заключенных в фигурные скобки. Эта инструкция используется для группирования других инструкций. Дело заключается в том, что внутри некоторых управляющих конструкций допускается использование единственной инструкции. Составную инструкцию следует применять в тех же случаях, когда в соответствии с

45

Источник: https://studfile.net/preview/16544272/