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

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

Запятая в качестве операции (ранг 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

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

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

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

 

 

Результат

 

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

 

 

 

 

Значения типов char и short

всегда преобразуются в int

14

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

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

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

Можно применять также последовательные присваивания, например: sum=a= b. В таких случаях присваивание производится справа налево, то есть b будет присвоено a, которая в свою очередь будет присвоена sum, так что все три переменных получат одно и то же значение (а именно, начальное значение b).

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

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

a = a + b;

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

a += b;

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

a –= b;

a = a * b;

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

a *= b;

a = a / b;

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

a /= b;

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

a %= b;

Пример:

Вычислите X3 и X10 , используя четыре операции умножения для заданного целого значения 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 ’ы — это библиотечные функции, которые сами написаны на Си. Это позволило создателям языка Си ограничиться небольшим числом операторов.

Обратите внимание на то, что, в отличие от Паскаля, символ точки с запятой в Си считается не разделителем операторов, а частью синтаксиса самих операторов (притом не всех).

Иначе говоря, если синтаксисом оператора предусмотрена точка с запятой, то она будет нужна там вне всякой зависимости от контекста; если же она не предусмотрена — то её там не будет (это значит, что компилятор без всякой точки с запятой знает, как распознать конец такого оператора).

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

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

Подчеркнём ещё раз, это никакой не «оператор присваивания», такого в Си просто нет. Это оператор вычисления выражения ради побочного эффекта, а само выражение построено на основе бинарной арифметической операции — присваивания.

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

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

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

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

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

Циклы:

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

 

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

 

for…

Возврат из функции:

return

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

break; continue; return; goto;

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

switch

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

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

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

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

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

Составное присваивание: +=; -=; *=; /=; %=; &=; |=; ^=; <<=; >>=;

Операторы работы с указателями: *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>6.3 (x-4)*3==12 6<=44

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

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

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

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

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

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

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

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

Например, если a, b, c - переменные, соответствующие длинам сторон треугольника, то для них должно быть истинно, то есть не равно 0, следующее логическое выражение:

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

Несколько операций одного ранга выполняются слева направо,

причем вычисления прерываются, как только будет определена истинность (или ложность) результата, то есть если в рассмотренном примере 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

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