Бинарные (двуместные) операторы

Бинарные операторы делятся на следующие группы:

- аддитивные;

- мультипликативные;

- сдвигов;

- поразрядные;

- операторы отношений;

- логические;

- присваивания;

- выбора компонента структурированного объекта;

- оператор "запятая";

- скобки в качестве операторов.

Аддитивные операторы:

+ - бинарный плюс - сложение арифметических операндов или сложение указателя с целочисленным операндом(ранг 4);

- - бинарный минус - вычитание арифметических операндов или вычитание указателей (ранг 4).

Мультипликативные операторы:

* - умножение операндов арифметического типа (ранг 3);

/ - деление операндов арифметического типа (ранг 3). При целочисленных операндах абсолютное значение результата округляется до целого. Например, 20/3 равно 6, -20/3 равно -6, (-20)/3 равно -6, 20/(-3) равно -6;

% - получение остатка от деления целочисленных операндов (деление по модулю - ранг 3). При неотрицательных операндах остаток положительный. В противном случае остаток определяется реализацией. В компиляторе Turbo C:

13%4 равняется 1, (-13)%4 равняется -1;

13%(-4) равно +1, а (-13)%(-4) равняется -1. При ненулевом делителе для целочисленных операндов всегда выполняется соотношение: (a/b)*b+a%b=a .

Операторы сдвига (определены только для целочисленных операндов). Формат выражения с оператором сдвига:

операнд_левый оператор_сдвига операнд_правый

<< - сдвиг влево битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого целочисленного операнда (ранг 5);

>> - сдвиг вправо битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого целочисленного операнда (ранг 5).

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

& - поразрядная конъюнкция (И) битовых представлений

значений целочисленных операндов (ранг 8);

! - поразрядная дизъюнкция (ИЛИ) битовых представлений значений целочисленных операндов (ранг 10);

^ - поразрядное исключающее ИЛИ битовых представлений значений целочисленных операндов (ранг 9).

Результат выполнения операторов сдвига и поразрядных операторов:

4<<2 равняется 16;

5>>1 равняется 2;

6&5 равняется 4;

6|5 равняется 7;

6^5 равняется 3.

Напоминаем, что двоичный код для 4 равен 100, для 5 - это 101, для 6 - это 110 и т.д. При сдвиге влево на две позиции код 100 становится равным 10000 (десятичное значение равно 16). Остальные результаты операторов сдвига и поразрядных операторов могут быть прослежены аналогично,

Обратите внимание, что сдвиг влево на n позиции эквивалентен умножению значения на 2**n, а сдвиг кода вправо уменьшает соответствующее значение в 2**n раз с отбрасыванием дробной части результат. (Поэтому 5>>1 равно 2).

Операторы отношений (сравнения):

< меньше, чем (ранг 6};

> больше, чем (ранг 6);

<= меньше или равно (ранг 6);

>= больше или равно (ранг 6);

== равно (ранг 7);

!= не равно (ранг 7).

Операнды операторов отношений должны быть арифметического типа или могут быть указателями. Результат целочисленный: 0 (ложь) или 1 (истина), Последние две операторы (операторы сравнения на равенство) имеют более низкий приоритет по сравнению с остальными операторми отношении. Таким образом, выражение

(x < B == A < x) есть 1 тогда и только тогда, когда значение x находится в интервале от A до B и A < B. (Вначале вычисляются

х < В и А < х, а к результатам применяется оператор сравнения на равенство ==.)

Логические бинарные операторы:

&& - конъюнкция (И) арифметических операндов или отношений (ранг 11}. Целочисленный результат 0 (ложь) или 1 (истина);

|| - дизъюнкция (ИЛИ) арифметических операндов или

отношений (ранг 12). Целочисленный результат 0

(ложь) или 1 (истина).

(Вспомните о существовании унарной операторы отрицания '!'.) Результаты отношений и логических операторов:

3 < 5 равняется 1;

3 > 5 равняется 0;

3 == 5 равняется 0;

3 != 5 равняется 1;

3!=5 || 3=5 равняется 1;

3+4>5 && 3+5>4 && 4+5>3 равняется 1.

Операторы присваивания (ранг 14):

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

(l-значение), т.е., ссылка на некоторую именованную область памяти, значение которой доступно изменениям.

Перечислим операторы присваивания, отметив, что существуют одна простой оператор присваивания и ряд составных операторов:

= - простое присваивание: присвоить значение выражения-операнда из правой части операнду левой части.

Пример:

Р = 10.3 - 2*х;

*= - присваивание после умножения: присвоить операнду левой части произведение значений обоих операндов Р *= 2 эквивалентно Р = Р * 2;

/= - присваивание после деления: присвоить операнду левой части частное от деления значения левого операнда на значение правого, Р /= 2.2 - d эквивалентно Р = Р / (2.2 - d );

%= - присваивание после деления по модулю: присвоить операнду левой части остаток от целочисленного деления значения левого операнда на значение правого операнда- N %= 3 эквивалентно N = N % 3;

+= - присваивание после суммирования: присвоить операнду левой части сумму значений обоих операндов А += В эквивалентно А = А + В;

-= - присваивание после вычитания: присвоить операнду левой части разность значении левого и правого операндов, X-=4.3-Z эквивалентно X=X-(4.3-Z);

<<= - присваивание после сдвигов разрядов влево: присвоить целочисленному операнду левой части значение, полученное сдвигом влево его битового представления на количество разрядов, равное значению правого целочисленного операнда, Например, а <<= 4 эквивалентно а = а << 4;

>>= - присваивание после сдвигов разрядов вправо: присвоить целочисленному операнду левой части значение, полученное сдвигом вправо его битового представления на количество разрядов, равное значению правого целочисленного операнда- Например, а >>= 4 эквивалентно а = а >> 4;

&= - присваивание после поразрядной конъюнкции: присвоить целочисленному операнду левой части значение, полученное поразрядной конъюнкции (И) его битового представления с битовым представлением целочисленного операнда правой части e &= 44 эквивалентно e = e & 44;

|= - присваивание после поразрядной дизъюнкции: присвоить целочисленному операнду левой части значение, полученное поразрядной дизъюнкцией (ИЛИ) его битового представления с битовым представлением целочисленного операнда правой части a |= b эквивалентно a = a | b;

^= - присваивание после исключающего поразрядного "ИЛИ": присвоить целочисленному операнду левой части значение, полученное применением поразрядной операторы исключающего ИЛИ к битовым представлениям значении обоих операндов z^= x+y эквивалентно z = ^(x+y). Обратите внимание, что для всех составных операторов присваивания форма присваивания Е1 ор = Е2 эквивалентна Е1 = Е1 ор (Е2), где ор - обозначение операторы.

Операторы выбора компонентов структурированного объекта:

. (точка) - прямой выбор (выделение) компонента структурированного объекта, например объединения или структуры {ранг 7). Формат применения оператора:

имя_структурированного_объекта. имя_компонента.

-> - косвенный выбор (выделение) компонента структурированного объекта, адресуемого указателем (ранг 1). При использовании операторы требуется, чтобы с объектом был связан указатель. В этом случае формат применения оператора имеет вид:

указатель_на_структурированный_объект -> имя_компонента.

 

Запятая в качестве операторов (ранг 15)

Несколько выражений, разделенных запятыми ",", вычисляются последовательно слева направо. В качестве результата сохраняются тип и значение самого правого выражения. Таким образом, оператор "запятая" группирует вычисления слева направо- Тип и значение результата определяются самым правым из разделенных запятыми операндов (выражении), Значения всех левых операндов игнорируются- Например, если переменная х имеет тип int , то значением выражения (х=3, 3*х) будет 9, а переменная х примет значение 3.

Скобки в качестве оператора (ранг 1)

Круглые скобки обязательны в обращении к функции:

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

В выражении имя_массива[индекс] операндами для оператора [ ] служат имя_массива и индекс.

Условный трехместный оператор (ранг 13)

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

выражвние_1 ? выражение_ 2 : выражение_3

Первым вычисляется значение выражения_1. Если оно истинно, т.е. не равно нулю, то вычисляется значение выражения_2, которое становится результатом. Если при вычислении выражения_1 получится 0, то в качестве результата берется значение выражения_3. Классический пример:

х < 0 ? -х : х;

Выражение возвращает абсолютную величину переменной х.

 Оператор явного преобразования типа.

Оператор преобразования (приведения) типа (ранг 2) имеет следующий формат:

(имя_типа) операнд

Такое выражение позволяет преобразовывать значение операнда к заданному типу. В качестве операнда используется унарное выражение, которое в простейшем случае может быть переменной, константой или любым выражением, заключенным в круглые скобки. Например, преобразования (long)8 (внутреннее представление результата имеет длину 4 байта) и (char)8 (внутреннее представление результата имеет длину 1 байт) изменяют длину внутреннего представления целых констант, не меняя их значений.

В этих преобразованиях константа не меняла значения и оставалась целочисленной. Однако возможны более глубокие преобразования, например, (long double) 6 или (float)4 не только изменяют длину константы, но и структуру ее внутреннего представления. В результатах будут выделены порядок и мантисса значения будут вещественными.

1.7 Разделители

Разделители входят в число лексем языка:

[ ] ( ) {} , ; : … * = #

Квадратные скобки могут использоваться для ограничения индексов массивов или для записи индексированных переменных. Int A[5] – одномерный массив из пяти элементов целого типа, double B[2][3]- двумерный массив из 6 элементов высокой точности. B[1][2]=1.3;

Круглые скобки предназначены для:

- выделения выражений в условном операторе;

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

float F( int i, double d) -/*заголовок функции*/

float F( int , double ); - /*прототип функции*/

- обязательны при определении указателя на функцию :

int (*pointer_to_function)(); /*указатель на функцию*/

- изменяют естественную последовательность операторов;

- являются обязательными элементами в операторах циклов;

- необходимы при явном преобразовании типов;

- используются в препроцессорных макроопределениях.

Фигурные скобки используются для

- обозначения начала и конца составного оператора ( аналог begin end скобок Паскаля);

- для выделения списка компонентов в определениях структурных и объединяющих типов:

/*Определение структурного типа cell*/

struct cell {

int i;

float f;

long double r};

/*Определение объединяющего типа mix*/

union mix {

long int i;

float f;

};

- при инициализации массивов и структур при их определении.

Запятая.

- Разделяет элементы списков, напр. списков инициализации массивов и структур, формальных параметров и их спецификаций в функциях;

- может разделять элементы в заголовке оператора цикла;

- используется в описаниях объектов одного типа.

Точка с запятой. Список выражений языка С или выражение, которое заканчивается точкой с запятой считается оператором. Каждое объявление, определение, и исполняемые операторы в программе С, должны заканчиваться этим знаком.

Двоеточие применяют для отделения метки от оператора, а многоточие – три точки без пробелов – для обозначения переменного числа параметров у функции при ее определении и описании (в прототипе).

Звездочка в описаниях и определениях означает, что объект или тип является указателем (адресом).

Знак номера, если он первый отличный от пробела символ в строке определяет строку как директиву препроцессора.

 

Модуль 2 ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ В С/С++

(6 часов)

Содержание модуля: Структура и элементы программы С/С++. Деление операторов языка С на группы. Выражения. Блоки и составные операторы. Управляющие операторы С/С++. Условная компиляция и замены в тексте программы С/С++. Стандартные библиотеки С/С++.

2.1 Структура и элементы программы С/С++

§ Текст программы и препроцессор.

Программа на языке Си должна быть оформлена в виде одного или нескольких текстовых файлов. Каждая программа на языке Си есть последовательность препроцессорных директив, объявлений и определений глобальных и локальных объектов и функций. Препроцессорные директивы (мы рассмотрели директивы #include и #define) управляют преобразованием текста программы до ее компиляцию Определения вводят функции и объекты. Объекты необходимы для представления в программе обрабатываемых данных. Функции определяют потенциально возможные действия программы. Объявления уведомляют компилятор о типах и именах тех объектов и функций, которые определены в других частях программы (например, ниже по ее тексту или в другом файле.

Рис. 2.1 Схема подготовки исполняемой программы на С

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

Исходная программа, подготовленная на языке Си в виде текстового файла, проходит три обязательных этапа обработки
(рис 2.1):

• препроцессорное преобразование текста;

• компиляция;

• компоновка (редактирование связей или сборка)

Только после успешного завершения всех перечисленных этапов формируется исполняемый машинный код программы.

Задача препроцессора - преобразование текста программы до ее компиляции. Правила препроцессорной обработки определяет программист с помощью директив препроцессора. Каждая препроцессорная директива начинается с символа '#'.

Препроцессор "сканирует" исходный текст программы в поиске строк, начинающихся с символа '#'- Такие строки воспринимаются препроцессором как команды (директивы), которые определяют действия по преобразованию текста. #define указывает правила замены в тексте. Директива #include определяет, какие текстовые файлы нужно включить в этом месте текста программы.

Директива #include<…> предназначена для включения в текст программы текста файла из каталога "заголовочных файлов, поставляемых вместе со стандартными библиотеками компилятора. Каждая библиотечная функция, определенная стандартом языка Си, имеет соответствующее объявление (прототип библиотечной функции плюс определения типов, переменных, макроопределений и констант) в одном из заголовочных файлов. Список заголовочных файлов для стандартных библиотек определен стандартом языка.

 

§ Структура простой программы на С

Приведем пример типичной организации небольшой программы на С. Обычно первой по порядку в функцией тексте программы является главная функция main.

/*Заголовки и комментарии программы*/

/*Включаемые файлы*/

#include имя_файла_1

#include имя_файла_2

. . .

#include имя_файла_n

/*Макро подстановки*/

#define макро1 значение1

#define макро1 значение2

. . .

#define макро1 значениеn

/*Объявления глобальных переменных*/

тип_1 глобальная_переменная_1;/*появилась ;*/

. . .

типn глобальная_переменная_n;

/*Главная функция программы*/

тип_результата main(список параметров)

/*тело функции в фигурных скобках*/

/*Начало блока функции*/ {

тип_1 локальная_переменная_1;/*появилась ;*/

. . .

тип_n локальная_переменная_n;

/*Список операторов main*/

return(объект_типа_функции);

/*Конец блока функции*/}

/*Функии применяемые в main аналогичной структуры*/

Рис. 2 Структура С программы

Функция main() является той функцией программы, которая запускается на исполнение по команде операционной системы. Возвращаемое ей значение также передается ОС. Если не предусматривается анализ этого значение можно указать пустой тип результата void. По умолчанию тип результата main() int.