2809

Операции как символ или комбинация символов

Лекция

Информатика, кибернетика и программирование

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

Русский

2012-10-19

136 KB

4 чел.

Лекция 7-8

Операции

Операция – это символ или комбинация символов, которые сообщают компилятору о необходимости произвести определённое арифметическое, логическое или другое действие. Операции в языке C  могут иметь от одного до трёх операндов и называются соответственно:

  •  унарные – действие, задаваемое знаком операции, выполняется с одним операндом, форма записи: «операция операнд»;
  •  бинарные – действие, задаваемое знаком операции, выполняется с двумя операндами, форма записи: «операнд операция операнд»;
  •  тернарные – действие, задаваемое знаком операции, выполняется с тремя операндами, форма записи: «операнд операция операнд операция операнд».

Каждая операция может иметь только определённые типы операндов.

Приоритет операции – свойство, задающее очерёдность выполнения операций, составляющих вычисляемое выражение.

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

Пример 1.

x=y=a+b+c

 4  3  1  2 – последовательность выполнения операций

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

Операция

Описание

Приоритет

Ассоциативность

Первичные

[]

обращение к элементу массива

16

()

вызов функции

16

.

обращение к члену структуры

16

->

обращение к члену структуры

16

Унарные операции

++

постфиксный инкремент

15

--

постфиксный декремент

15

++

префиксный инкремент

14

--

префиксный декремент

14

sizeof()

размер в байтах

14

(тип)

преобразование типа

14

~

побитовое НЕ

14

!

логическое НЕ

14

+

унарный плюс

14

-

унарный минус

14

&

взятие адреса

14

*

обращение по адресу

14

Бинарные и тернарные операции

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

*

умножение

13

/

деление

13

%

деление по модулю

13

Аддитивные

+

сложение

12

-

вычитание

12

Побитовый сдвиг

<<

сдвиг влево

11

>>

сдвиг вправо

11

Отношение

<

меньше, чем

10

>

больше, чем

10

<=

меньше или равно, чем

10

>=

больше или равно, чем

10

Равенство

==

равно

9

!=

не равно

9

Битовые

&

побитовое И

8

^

побитовое исключающее ИЛИ

7

|

побитовое ИЛИ

6

Логические

&&

логическое И

5

||

логическое ИЛИ

4

Условные

?:

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

3

Присваивание

=

присваивание

2

*=

присвоение произведения

2

/=

присвоение частного

2

%=

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

2

+=

присвоение суммы

2

-=

присвоение разности

2

<<=

присвоение левого сдвига

2

>>=

присвоение правого сдвига

2

&=

присвоение И

2

^=

присвоение исключающего ИЛИ

2

|=

присвоение ИЛИ

2

,

последовательное вычисление

1

Первичные операции.

Операция «обращение к элементу массива» будет подробно рассмотрена при изучении массивов.

Операция «вызов функции» будет подробно рассмотрена при изучении функций.

Операции «обращение к члену структуры» будут подробно рассмотрены при изучении структур.

Унарные операции «взятие адреса» и «обращение по адресу» будут подробнее рассмотрены при изучении указателей.

Унарная операция «преобразование типа» используется для явного преобразования типа объекта в другой тип. Форма записи: (тип)операнд. Допустимый тип операнда и тип преобразования – тип объекта языка C.

Пример 2

float f=2.5;

double d=(double)f;

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

Пример 3

float f=2.5;

int i=(int)f;

printf("%d %d",i,(int)f);

Переменная i будет иметь значение 2, а функция printf() напечатает: 2 2

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

Унарные арифметические операции инкремента и декремента в постфиксной и префиксной формах. Это унарные операции присваивания. Операция инкремента «++» прибавляет единицу к операнду, операция декремента «--» вычитает единицу от операнда. Префиксная форма – в вычислении выражения, в которое входит операция, используется изменённое значение операнда. Постфиксная форма – в вычислении выражения, в которое входит операция, используется исходное значение операнда, а потом производится изменение.

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

Префиксная

Постфиксная

Инкремент

++операнд

операнд++

Декремент

--операнд

операнд--

Тип операнда – целый, вещественный или указатель (указатель типа void недопустим). Операнд обязательно должен быть модифицируемым. Тип результата эквивалентен типу операнда.

Пример 4

int i=5;

i--;

printf("%d",i++);

printf(" %d",++i);

--i;

printf(" %d ",++i);

На экране будет напечатано: 4 6 6

Унарные арифметические операции «унарный плюс» и «унарный минус». Операция «унарный минус» преобразовывает знак операнда на противоположный. Форма записи: -операнд. Операнд должен быть целой или вещественной знаковой величиной, тип результата эквивалентен типу операнда.

Пример 5

int i=5;

i=-i;

Операция «унарный плюс» не изменяет значение операнда явно, но запрещает компилятору реорганизовывать скобочные выражения, таким образом влияя на результат вычисления значений операнда, заключенного в круглые скобки. Форма записи: +операнд.

Пример 6

int a=30,b=4,c=3,d=+(a*b)/c;

printf(“%d”,d);

На экране будет напечатано: 40

Арифметические мультипликативные операции.

Это операции «умножение», «деление» и «деление по модулю».

Операция «умножение» реализует умножение первого операнда на второй. Форма записи: операнд1*операнд2. Операция «деление» реализует деление первого операнда на второй. Форма записи: операнд1/операнд2. Типы операндов могут отличаться, в данном случае используется неявное преобразование типов, результат будет иметь тип операндов после преобразования типов. При делении двух целых чисел результат округляется до ближайшего меньшего целого числа, а остаток отбрасывается. Типы операндов – любые базовые типы с использованием модификаторов, за исключением типа void.

Операция «деление по модулю» получает остаток от целочисленного деления первого операнда на второй, операндами должны быть целые числа, результат – также целое число. Форма записи: операнд1%операнд2.

Знак результата операций «умножение» и «деление» зависит от знаков операндов, знак результата операции «деление по модулю» совпадает со знаком делимого.

Пример 7

int a=-30,b=4,c=30,d=-4;

printf("%d %d %d %d %d",a*b,a/b,a%b,c*d,c%d);

На экране будет напечатано: –120 –7 –2 –120 2

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

Это операции «сложение» и «вычитание».

Операция «сложение» реализует сложение первого и второго операндов. Форма записи: операнд1+операнд2. Операция «вычитание» реализует вычитание второго операнда из первого. Форма записи: операнд1-операнд2. Возможные операнды:

  •  целые и вещественные числа, тип результата зависит от неявного преобразования типов операндов;
  •  первый операнд – указатель, второй операнд – целое число, тип результата – указатель;
  •  указатели (только для операции «вычитания»), тип результата – целое число.

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

Пример 8

unsigned short int a=1000,b=1000,c=a*b;

printf("%d",c);

На экране будет напечатано: 16960

Операции сдвига.

Операции «сдвиг вправо» и «сдвиг влево» сдвигают все биты операнда на целое число позиций вправо или влево. Операции применимы только к целочисленным переменным. Форма записи: операнд1>>операнд2, операнд1<<операнд2, где операнд1 является сдвигаемым числом, а операнд2 определяет число позиций сдвига и должен быть положительным.

Для операции «сдвиг влево» недостающие значения битов справа дополняются нулями. Для операции «сдвиг вправо» недостающие значения битов слева дополняются нулями для беззнаковых чисел или копией старшего бита для знаковых чисел.

При применении операций сдвига может происходить потеря старших или младших разрядов. Применение операции «сдвиг вправо» и «сдвиг влево» по очереди к одной и той же переменной может изменить значение этой переменной из-за потери разрядов.

 

Пример 9

short int i=31251; // 0111 1010 0001 0011 (7A13)

unsigned short j=42397; // 1010 0101 1001 1101 (A59D)

i=i<<2; // 1110 1000 0100 1100 (E84C) (-6068)

j=j<<2; // 1001 0110 0111 0100 (9674) (38516)

i=i>>2; // 1111 1010 0001 0011 (FA13) (-1517)

j=j>>2; // 0010 0101 1001 1101 (259D) (9629)

Операции отношения и равенства.

Операции «меньше, чем», «больше, чем», «меньше или равно, чем», «больше или равно, чем», «равно» и «не равно» используются для сравнения операндов. Форма записи: операнд1<операнд2, операнд1>операнд2, операнд1<=операнд2, операнд1>=операнд2, операнд1==операнд2, операнд1!=операнд2. Допустимые типы операндов – целочисленные, вещественные и символьные величины, указатели (должны указывать на объекты одного типа).

Каждое условное выражение принимает значение «истинно» или «ложно». Так как в языке C нет логического (булевого) типа, результатом выражения является целое арифметическое значение, «истинно» – ненулевая величина (как правило, 1), «ложно» – 0.

Пример 10

float c=2.5;

int a=2==2,b=2,d=b>=c;

printf("%d %d",a,d);

На экране будет напечатано: 1 0

Битовые операции.

Операции «побитовое НЕ» (NOT), «побитовое И» (AND), «побитовое исключающее ИЛИ» (XOR), «побитовое ИЛИ» (OR) выполняются над парами соответствующих битов операндов («побитовое НЕ» выполняется только над одним операндом). Форма записи: ~операнд1, операнд1&операнд2, операнд1^операнд2, операнд1|операнд2. Допустимые типы операндов – целочисленные или символьные величины. Операнды должны быть одного и того же типа, иначе производится неявное преобразование типов. Тип результата совпадает с типом операндов.

Результат битовой операции для каждой пары битов определяется таблицей истинности данной операции.

X

Y

NOT X

X AND Y

X XOR Y

X OR Y

0

0

1

0

0

0

0

1

1

0

1

1

1

0

0

0

1

1

1

1

0

1

0

1

Пример 11

unsigned char x=0xDA, y=0xB3,a=~x,b=x&y,c=x^y,d=x|y;

printf("%X %d %X %d %X %d %X %d",a,a,b,b,c,c,d,d);

На экране будет напечатано: 25 37 92 146 69 105 FB 251.

    x=11011010

    y=10110011

  ~x=00100101

x&y=10010010

x^y=01101001

 x|y=11111011

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

Операции «НЕ» (NOT), «И» (AND), «ИЛИ» (OR) выполняются над парами операндов («НЕ» выполняется только над одним операндом). Форма записи: !операнд1, операнд1&&операнд2, операнд1||операнд2. Допустимые типы операндов – целочисленные, вещественные или символьные величины, указатели. Операнды могут быть разного типа, неявное преобразование типов не производится. Тип результата логической операции является целым арифметическим значением, «истинно» – ненулевая величина (как правило, 1), «ложно» – ноль.

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

Особенностью логических операций «И» и «ИЛИ» является то, что если при вычислении операции «И» операнд1 будет равен 0, то операнд2 вычисляться не будет, так как не окажет никакого влияния на результат (даже если операнд2 – это выражение, использующее унарную операцию инкремента или декремента), а если при вычислении операции «ИЛИ» операнд1 будет равен 1, то операнд2 также вычисляться не будет, так как не окажет никакого влияния на результат.

Результат логической операции определяется таблицей истинности данной операции.

Пример 12

int a=0,b=1,c=!(a==b),d=a&&a++,e=b||b++;

printf("%d %d %d %d %d",a,b,c,d,e);

На экране будет напечатано: 0 1 1 0 1

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

Операции «присваивание», «присвоение произведения», «присвоение частного», «присвоение остатка», «присвоение суммы», «присвоение разности», «присвоение левого сдвига», «присвоение правого сдвига», «присвоение И», «присвоение исключающего ИЛИ», «присвоение ИЛИ» используются для замены значения операнда. Форма записи: операнд1=операнд2, операнд1*=операнд2, операнд1/=операнд2, операнд1%=операнд2, операнд1+=операнд2, операнд1-=операнд2, операнд1<<=операнд2, операнд1>>=операнд2, операнд1&=операнд2, операнд1^=операнд2, операнд1|=операнд2.

При выполнении операции «присваивание» (простое присваивание) производится замещение значения левого операнда (операнд1) значением правого операнда (операнд2). При выполнении остальных операций присваивания (составное присваивание) производится замещение значения левого операнда (операнд1) значением выражения «операнд1 операция операнд2», где операция – это бинарная операция, знак которой определён перед знаком '='.

Пример 13

x+=y эквивалентно x=x+y

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

Пример 14

int a=2, b=3, c=4, d=a+(b+=c);

Операция «sizeof()».

Операция «sizeof()» вычисляет размер в байтах памяти, занимаемой операндом. Форма записи: sizeof(операнд)

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

Если в качестве операнда используется выражение или идентификатор, то возможно применение второй формы записи операции «sizeof()»:

sizeof операнд

Тип результата – unsigned int. Операция «sizeof()» выполняется на этапе компиляции программы.

Пример 15

int a=sizeof(double),b=sizeof(1.l+a);

printf("%d %d",a,b);

На экране будет напечатано: 8 10

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

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

Пример 16

struct s { char h;

               double f;

               short int b;

            } str;

int a1=sizeof(str),a2=sizeof(char)+sizeof(short int)+sizeof(double);

printf("%d %d",a1,a2);

На экране будет напечатано: 16 11

Пример 17

struct s { char h;

               short int b;

               double f;

            } str;

int a1=sizeof(str),a2=sizeof(char)+sizeof(short int)+sizeof(double);

printf("%d %d",a1,a2);

На экране будет напечатано: 12 11

Для примера 16 несоответствие имеет место в виду того, что после размещения в памяти первой переменной h длиной 1 байт, добавляется 3 байта для выравнивания адреса переменной f на границу двойного слова (слово имеет длину 2 байта для машин серии IBM PC), далее осуществляется размещение переменных f длиной 8 байтов и b длиной 2 байта, а затем добавляются ещё 2 байта для выравнивания адресов следующих элементов памяти на границу двойного слова. Таким образом, в результате операций выравнивания для размещения структуры в оперативной памяти требуется на 5 байтов больше.

Для примера 17 несоответствие имеет место в виду того, что после размещения в памяти первой переменной h длиной 1 байт, добавляется 1 байт для выравнивания адреса переменной b на границу слова, далее осуществляется размещение переменных b длиной 2 байта и f длиной 8 байтов. Таким образом, в результате операций выравнивания для размещения структуры в оперативной памяти требуется на 1 байт больше.

Подобные эффекты связаны с размещением переменных компилятором в процессе компиляции программы, что в свою очередь зависит от архитектуры ЭВМ и способов адресации процессора.

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

Форма записи: операнд1?операнд2:операнд3. Операнд1 – целое или вещественное число или указатель. Типы остальных операндов:

  •  если операнд2 или операнд3 имеет целый или вещественный тип (эти операнды могут быть разного типа), то выполняется неявное преобразование типа, и тип результата – тип операнда после преобразования;
  •  если операнд2 и операнд3 имеют один и тот же тип структуры, объединения или указателя, то тип результата будет тем же самым типом структуры, объединения или указателя;
  •  если оба операнда имеют тип void, то результат имеет тип void;
  •  если один операнд является указателем на объект любого типа, а другой операнд является указателем на тип vold, то указатель на объект преобразуется к указателю на тип vold, который и будет типом результата;
  •  если один из операндов является указателем, а другой константным выражением со значением 0, то типом результата будет тип указателя.

Операция вычисляет операнд1. Если он не равен 0, вычисляется операнд2, значение которого и будет результатом. Если операнд1 равен 0, вычисляется операнд3, значение которого и будет результатом. В любом случае вычисляется только один из операндов: операнд2 или операнд3.

Пример 18

int a=0,b=1,c=0;

printf("%d %d",a?b:c,b?++b:c);

На экране будет напечатано: 0 2

Операция «последовательное вычисление».

Форма записи: операнд1,операнд2. Операнды операции являются выражениями и могут быть любых типов. Тип и значение результата соответствуют типу и значению второго операнда. Операция используется для вычисления двух и более выражений там, где по синтаксису допустимо только одно выражение. При выполнении операции преобразование типов не производится.

Пример 19

for(int i=0,j=0;i<10&&j<20;i++,j++);

Побочные эффекты.

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

Пример 20

func(m*2,m=k+1);

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

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

Пример 21

int i,a[2]={5,5};

i=0;

a[i++]=i;

printf("%d %d %d",a[0],a[1],i);

На экране будет напечатано: 0 5 1

В общем же случае значение a[0] может быть неопределённым.

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

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


 

А также другие работы, которые могут Вас заинтересовать

60798. Створення головного меню і контекстного меню доданку 54 KB
  Вставка в форму головного і контекстного меню об‘єкти типу MinMenu і PopupMenu. Щоб ввести назви команд головного меню форми виберітьоб‘єкт MinMenu1 і двічі клацніть на його властивості Items.
60802. Моделювання виховної роботи з учнями, що мають різний соціометричний статус 61.5 KB
  Проведемо наше методичне об’єднання в нетрадиційній формі деякі засоби роботи вправи ви зможете використати в роботі з класом. Отже сьогодні чого ми очікуємо від процесу виховання Якими ми бачимо труднощі або результати...
60804. Особливості формування ключових компетентностей учнів через міжтематичні зв’язки системи теоретичних понять інформатики та реалізацію гуманітарних аспектів 373 KB
  Особливість предмету інформатики та визначення його ролі і міста серед предметів на формування загальної освіти особистості зміст його предметних та загальноосвітніх компетентностей вже створює проблеми в викладанні змісту...