Скачиваний:
2
Добавлен:
03.01.2024
Размер:
280.85 Кб
Скачать

Бинарные (двуместные) операции. Тернарная (трёхместная) операция

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

Несколько выражений, разделенных запятыми «,», вычисляют­ ся последовательно слева направо.

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

Таким образом, операция «запятая» группирует вычисления слева направо.

Тип и значение результата определяются самым правым из разделенных запятыми операндов (выражений).

Значения всех левых операндов­ игнорируются.

Например, если переменная x имеет тип int, то значением выражения (x=3, 3*x) будет 9, а переменная x примет значение 3

Скобки в качестве операций

Круглые ( ) и квадратные [ ] скобки играют роль бинарных операций (ранг 1) при вызове функций и индексировании элементов массивов.

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

И это даже тогда, когда он практически в каждой программе обращается к функциям или применяет индексированные переменные.

Итак, отметим, что скобки могут служить бинарными операциями, особенности и возможности которых достойны внимания.

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

имя_функции(список_аргументов)

где операндами служат имя_функции и список_аргументов.

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

В выражении имя_массива[индекс]

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

Тернарная (условная трехместная) операция (ранг 13).

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

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

Первым вычисляется значение выражения_1.

Если оно истинно, то есть не равно нулю, то вычисляется значение выражения_2, которое­ становится результатом.

Если при вычислении выражения_1 получится­ 0 (ложь), то в качестве результата берется значение выражения_3.

Классический пример:

x < 0 ? -x : x;

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

11

Обзор операций

Пример 1:

Смысл записи

Пример 2:

Значения

int i, j, k;

 

int n, a, b, c, d;

 

float x, y;

 

n = 2; a = b = c = 0;

 

...

 

a = ++n;

n=3, a=3

х *= y;

x = x*y;

a += 2;

a=5

i += 2;

i = i + 2;

b = n++;

b=3, n=4

x /= y+15;

x = x/(y + 15);

b –= 2;

b=1

--k;

k = k – 1;

c = --n;

n=3, c=3

k--;

k = k – 1;

c *= 2;

c=6

j = i++;

j = i; i = i + 1;

d = n--;

d=3, n=2

j = ++i;

i = i + 1; j = i;

d %= 2;

d=1

12

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

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

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

Такое выражение позволяет преобразовывать значение операнда к заданному типу.

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

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

В этих преобразованиях константа не меняла значения и оставалась­ целочисленной.

Однако возможны более глубокие преобразования,­ например

(long double)6

или (float)4

не только изменяют длину константы,

но и структуру ее внутреннего представления.

 

В результатах будут выделены порядок и мантисса, значения

будут вещественными.

 

 

Примеры:

 

 

 

 

long i = 12L;

/*

Определение переменной

*/

float brig;

/*

Определение переменной

*/

brig = (float)i;

/*

Явное приведение типа

*/

brig получает значение 12L, преобразованное к типу float.

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

При преобразовании больших целочисленных констант к вещественному типу (например, к типу float) возможна потеря значащих цифр (потеря точности).

Если вещественное значение преобразуется к целому, то возможна ошибка при выходе полученного значения за диапазон допустимых значений для целых.

В этом случае результат преобразования не всегда предсказуем и целиком зависит от реализации.

Тонкости терминологии: что такое оператор, операция, инструкция и кто из них operator, а кто statement?

Лучше говорить операция, так как оператор в англоязычной литературе, это нечто иное.

Вот когда оператором обзывают операцию (инструкцию), сиречь statement, вот тут, да, начинается путаница.

Оператор (statement) – часть программы, определяющая действие, предпринимаемое при выполнении программы.

Выражение, завершающееся точкой с запятой, является

оператором.

Такие операторы, как if, for и while, имеют блоки, способные содержать другие операторы.

Некоторые компиляторы без L не скомпилируют

13

 

Преобразование типов операндов арифметических операций

Если операнды

 

 

 

Но, как правило, в

арифметических

 

 

операциях участвуют

операндов имеют один

 

операнды различных типов.

тип, то и результат

 

 

 

В этом случае они

операции будет иметь

 

преобразуются к общему типу

такой же тип

 

 

в порядке увеличения их

 

 

 

«размера памяти», т.е.

 

 

Стрелки отмечают

 

 

объема памяти, необходимого

преобразования даже

 

 

для хранения их значений.

однотипных операндов

 

 

Поэтому неявные

перед выполнением

 

 

преобразования всегда идут от

операции

 

 

«меньших» объектов к

 

 

 

«большим».

 

 

 

 

 

short, char int

unsigned

long

double

 

 

 

 

float

double

Действуют следующие правила

Eсли один из операндов имеет тип double, то и другой преобразуется в double

Eсли один из операндов long, то другой преобразуется в long

Значения типов char и short всегда преобразуются в int

В Си различают явное и неявное преобразование типов данных.

Неявное преобразование типов данных выполняет компилятор, а явное преобразование данных выполняет сам программист.

Результат любого вычисления будет преобразовываться к наиболее точному типу данных, из тех типов данных, которые участвуют в вычислении.

x

y

Результат

Пример

деления

 

 

 

 

делимое

делитель

частное

x = 15 y = 2

 

 

 

 

int

int

int

15/2=7

 

 

 

 

int

float

float

15/2=7.5

 

 

 

 

float

int

float

15/2=7.5

 

 

 

 

14

 

 

Операция присваивания. Арифметические операции

 

 

 

 

 

 

Комбинированные операции

 

 

Операция присваивания

 

 

 

 

Ниже приводятся некоторые примеры выражений и способы их

 

Самой общей операцией является присваивание, например,

p=a/b или ch = getch(). В Си присваивание обозначается одним

сокращения:

 

a += b;

знаком равенства (=); при этом значение справа от знака

 

a = a + b; сокращается до

равенства присваивается переменной слева.

 

a = a – b;

сокращается до

a –= b;

 

Можно применять также последовательные присваивания,

 

a = a * b;

сокращается до

a *= b;

 

 

a = a / b; сокращается до

a /= b;

например: sum=a= b. В таких случаях присваивание производится

 

 

a = a % b; сокращается до

a %= b;

справа налево, то есть b будет присвоено a, которая в свою

 

очередь будет присвоена sum, так что все три переменных

 

Пример:

и X10 , используя четыре операции умножения для

получат одно и то же значение (а именно, начальное значение b).

 

Вычислите X3

 

 

 

заданного целого значения X.

 

 

 

Арифметические операции. Инкремент. Декремент

 

 

 

 

 

Си поддерживает обычный набор арифметических операций:

 

 

 

 

умножение (*)

 

 

 

 

 

деление (/)

 

 

 

 

 

определение остатка от деления (%)

 

 

сложение (+)

 

 

 

 

 

вычитание ()

 

 

 

 

Для увеличения значений переменной на единицу используют

инкремент (++), для уменьшения на единицу декремент (--).

 

Так :

 

 

 

 

 

x++; // увеличивает x на единицу

 

y--; // уменьшает y на единицу

 

Примеры постфиксных и префиксных операций:

 

a=2;

 

a=2;

 

x=18–2*a++;

x=18–2*(++a);

 

Получим :

a=3

 

a=3

 

 

x= 14

 

x=12

#include <stdio.h> int x,x2,x3,x5,x10; main()

{

printf("\n Программа расчета X^3 и X^10\n"); puts("Введите значение X");

scanf("%i",&x);

x2=x*x;

x3=x*x2;

x5=x2*x3;

x10=x5*x5;

printf("%i в 3–ей степени = %i \n",x,x3); printf("%i в 10–ой степени = %i",x,x10);

}

15

Операция запятая (,)

Операция запятая

Данная операция используется при организации строго гарантированной последовательности вычисления выражений.

Форма записи:

выражение1, …, выражениеN;

выражения1,…,N вычисляются гарантированно последовательно и результатом операции становится значение выражения N.

Пример:

m=(i=1, j=i++, k=6, n=i+j+k);

получим последовательность вычислений:

i=1, j=i=1, i=2, k=6, n=2+1+6, в результате m=n=9.

Пример:

int x=1, y=2, z; z=(x++, x-y); // z=0

z=x++, x-y; /* z=1, т.к. оператор ″,″ имеет наименьший приоритет из всех операторов */

Другим вариантом использования оператора for является бесконечный цикл. Для организации такого цикла можно использовать пустое условное выражение, а для выхода из цикла обычно используют дополнительное условие и оператор break.

Пример: for (;;)

{ ...

... break;

}...

 

 

 

Введение в операторы

 

 

 

 

Пример (на for):

 

 

Операции и операторы.

for (<инициализация>; <условие>;

<выражение>) оператор1;

 

 

 

 

 

[else оператор2;]

 

 

 

for (i=0; i <n; i = i+l) a[i]=0;

 

Этот оператор устанавливает первые n элементов массива a

 

равными нулю.

 

 

 

 

Выполнение оператора начинается с установки i в ноль (это

 

делается вне цикла).

Затем оператор повторяется до тех пор, пока i < n, выполняя при

 

этом присваивание и увеличение i.

Вместо оператора присвоения значения текущему элементу

 

массива нуля может быть составной оператор (блок),

 

заключенный в фигурные скобки.

Некоторые варианты использования оператора for повышают его

 

гибкость за счет возможности использования нескольких переменных,

 

управляющих циклом:

 

 

int main()

 

{

int top, bot;

 

 

 

char string[100], temp;

 

 

 

for ( top=0, bot=100 ; top < bot ; top++, bot--)

 

 

 

{ temp=string[top];

 

 

 

} string[bot]=temp;

 

}

return 0;

В этом примере, реализующем запись строки символов в обратном

 

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

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

16

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

2. Операторы

 

 

 

Оператор – это наименьшая автономная часть языка

Пустой оператор ;

 

 

 

программирования, команда (это наименьшая исполняемая

Составной оператор (блок); локальные переменные

единица программы).

 

В Си часто возникает потребность объединить несколько операторов

Количество операторов в языке Си гораздо меньше, чем в

в один.

 

 

 

 

 

Паскале, потому что все возможности, которые только могут быть

 

 

 

 

 

вытеснены из языка в библиотеку, реализованы именно в

Локальные переменные (и другие локальные имена, о которых

библиотеке.

Как уже говорилось, в Си (самом по себе) отсутствуют какие

мы узнаем позже) описываются в самом начале блока, сразу после

открывающей фигурной скобки { и до появления в блоке первого

бы то ни было средства ввода-вывода, а всевозможные printf ’ы и

scanf ’ы — это библиотечные функции, которые сами написаны

оператора.

 

 

 

 

Ветвление:

if ( <условие> ) <оператор 1> [ else <оператор 2> ]

на Си. Это позволило создателям языка Си ограничиться

небольшим числом операторов.

Циклы: while ( <условие> ) <оператор>;

Обратите внимание на то, что, в отличие от Паскаля, символ

 

 

 

do <оператор> while ( <условие> ) ;

точки с запятой в Си считается не разделителем операторов, а

 

 

 

for…

 

 

 

частью синтаксиса самих операторов (притом не всех).

Возврат из

 

 

 

функции:

 

return

Иначе говоря, если синтаксисом оператора предусмотрена

Операторы перехода:

 

break; continue; return; goto;

точка с запятой, то она будет нужна там вне всякой зависимости

Оператор выбора: switch

 

 

от контекста; если же она не предусмотрена — то её там не будет

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

&&; ИЛИ ||; НЕ !;

(это значит, что компилятор без всякой точки с запятой знает, как

Оператор сравнения:

==; !=; >; <; >=; <=;

распознать конец такого оператора).

Побитовые операторы: ~; &; |; ^; <<; >>;

Оператор вычисления выражения: x + 5; x = 17;

Составное присваивание:

+=; -=;

*=; /=; %=; &=; |=; ^=; <<=;

Это произвольное арифметическое выражение, после

которого стоит точка с запятой — она как раз и превращает

>>=;

 

 

 

 

 

выражение (которое могло бы быть частью другого

Операторы работы с указателями:

 

*a; *a; a->b; a.b; a->*b; a.*b;

выражения) в законченную конструкцию — оператор.

 

 

 

 

 

 

 

 

Другие операторы:

 

 

 

Подчеркнём ещё раз, это никакой не «оператор

 

 

 

Оператор «запятая»;

 

 

присваивания», такого в Си просто нет. Это оператор

 

 

 

Тернарная условная операция;

 

вычисления выражения ради побочного эффекта, а само

 

 

 

Sizeof (размер);

 

 

 

выражение построено на основе бинарной арифметической

 

 

 

и др.

 

 

 

 

 

 

 

 

операции — присваивания.

 

 

 

 

 

 

 

 

17

3. Выражения

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

Каждое выражение состоит из одного или нескольких операндов, символов операций и ограничителей, в качестве которых чаще всего выступают круглые скобки ( ).

Назначение любого выражения – формирование некоторого значения.

В зависимости от типа формируемых значений определяются

типы выражений.

Если значениями выражения являются целые и вещественные числа, то говорят об арифметических выражениях.

Арифметические выражения

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

операции (рассматривали в предыдущих вопросах): + сложение (или унарная операция +);

- вычитание (или унарная операция изменения знака); * умножение; / деление;

% деление по модулю (то есть получение остатка от целочисленного­ деления первого операнда на второй).

Операндами для перечисленных операций служат константы

и переменные арифметические типы, а также выражения,

заключенные­ в круглые скобки.

 

Примеры выражений с двумя операндами:

a+b 12.3-x

3.14159*Z

k/3 16%i

Нужно быть аккуратным, применяя операцию деления '/' к цело-численным операндам.

Например, за счет округления результата значением выражения 5/3 будет 1, а соответствует ли это замыслам программиста, зависит от смысла той конкретной конструкции, в которой это выражение используется.

Чтобы результат выполнения арифметической операции был вещественным, необходимо, чтобы вещественным был хотя бы один из операндов.

Например, значением выражения 5.0/2 будет 2.5, что соответствует смыслу обычного деления.

Как уже говорилось, введены специфические унарные операции ++ (инкремент) и -- (декремент) для изменения на «1»

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

Каждая из этих операций может быть префиксной и постфиксной.

Внешнюю неоднозначность имеют выражения, в которых знак

унарной операции ++ (или --) записан непосредственно рядом со

знаком бинарной операции +:

 

x+++b или z---d

 

В этих случаях трактовка выражений однозначна и полностью

определяется рангами операций (бинарные аддитивные + и -

имеют ранг 4; унарные ++ и -- имеют ранг 2). Таким образом:

x+++b эквивалентно (x++)+b

z---d эквивалентно (z--)-d

18

Отношения и логические выражения

 

 

 

Они перечислены по убыванию старшинства (ранга).

 

Отношение определяется как пара арифметических

 

 

выражений, соединенных (разделенных) знаком операции

 

Как правило, логические операции применяются к

 

отношения.

 

отношениям.

 

Знаки операций отношения (уже были введены выше):

 

 

 

До выполнения логических операций вычисляются значения

 

== равно;

 

отношений, входящих в логическое выражение.

 

!= не равно;

 

Например, если a, b, c - переменные, соответствующие длинам

 

< меньше, чем;

 

сторон треугольника, то для них должно быть истинно, то есть не

 

> больше, чем;

 

равно 0, следующее логическое выражение:

 

<= меньше или равно;

a+b>c && a+c>b && b+c>a

 

>= больше или равно.

 

 

Примеры отношений:

a-b>6.3 (x-4)*3==12 6<=44

Логический тип в языке Си (С89) отсутствует, поэтому принято, что отношение имеет ненулевое значение (обычно 1), если оно истинно, и равно 0, если оно ложно.

Таким образом, значением отношения 6<=44 будет 1.

Операции >, >=, <, <= имеют один ранг 6.

Операции сравнения на равенство == и != также имеют одинаковый, но более низкий ранг 7, чем остальные операции отношений.

Арифметические­ операции имеют более высокий ранг, чем операции отношений, поэтому в первом примере для выражения а-b не нужны скобки.

Несколько операций одного ранга выполняются слева направо, причем вычисления прерываются, как только будет определена истинность (или ложность) результата, то есть если в рассмотренном примере a+b окажется не больше c, то остальные отношения не рассматриваются - результат ложен.

Так как значением отношения является целое (0 или 1), то ничто не противоречит применению логических операций к целочисленным значениям.

При этом принято, что любое ненулевое положительное значение воспринимается как истинное, а ложной считается только величина, равная нулю.

Значением !5 будет 0, значением 4 && 2 будет 1 и т. д.

19

Выражения и операторы

Понятие R-value и L-value:

Данные в Си могут представляться литералами и переменными (и те и другие хранят значения данных в областях памяти).

Это хранимое значение называется R-value (read value), т.е.

значение, которое можно прочитать.

Значение адреса области памяти для хранения значения переменной называется L-value (location value), т.е. значение, которое определяет местоположение.

Фундаментальное различие между литералами и переменными заключается в том, что переменная именует область памяти, в которой хранится R-value, а литерал – нет.

Переменная определяет как R-value так и L-value, а литерал

только R-value.

Присваивание может включать несколько операций присваивания:

int i, j, k;

float x, y, z;

y=10; //y=10 i=j=k=0; //k=0, j=k, i=j

--------

x=i+(y=3)-(z=0); //z=0, y=3, x=i+y-z;

 

Примеры недопустимых выражений:

 

присваивание константе:

2 = x+y;

 

 

присваивание функции:

getch() = i;

 

 

присваивание результату операции:

(i+1) = 2+y;

Любое выражение, которое заканчивается точкой с запятой, является оператором.

Пустой оператор состоит только из точки с запятой.

Синтаксис языка СИ требует, чтобы после метки обязательно следовал оператор. Фигурная же скобка оператором не является.

Поэтому, если надо передать управление на фигурную скобку, необходимо использовать пустой оператор:

label1:; { // код на Си return 0;

}

Программа:

Операторы; …;

Выражения…

Операнды, Операции, Скобки…

Переменные, Константы, Выражения

20

Соседние файлы в папке Лекции