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.  Не использовать операции присваивания переменной в выражении, если эта переменная используется в выражении более одного раза.


 

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

30267. Характерологический уровень текста. Способы психологической характеристики персонажа: характеристика через биографию, через художественную деталь, через точку зрения других персонажей и др 23 KB
  Образ героя художественного произведения складывается из множества факторов – это и характер и внешность и профессия и увлечения и круг знакомств и отношение к себе и окружающим. Один из главных – речь персонажа в полной мере раскрывающая и внутренний мир и образ жизни.Характеризующая чтобы лучше раскрыть образ героя его индивидуальность подчеркнуть какието черты характера или принадлежность к определенной группе профессиональной этнической социальной особенности воспитания.Выделительная чтобы сделать образ запоминающимся...
30268. Сюжетно-композиционный уровень текста. Сюжет. Мотив. Фабула 35.5 KB
  Сюжет. Фабула Сюжет то что происходит в произведении; система основных событий и конфликтов система событий художественного произведения раскрывающая характеры героев и способствующая наиболее полному выражению идейного содержания. Система событий единство развивающееся во времени а движущей силой сюжета является конфликт. Сюжет может излагаться: в прямой хронологической последовательности событий; с отступлениями в прошлое ретроспективами и экскурсами в будущее; в преднамеренно измененной последовательности.
30269. Пространственно-временной уровень текста. Способы организации художественного пространства 24.5 KB
  Понятие о хронотопе М. Виды хронотопов: Пространственновременная организация литературного произведения хронотоп. Под хронотопом М. По Бахтину хронотоп в первую очередь принадлежность романа.
30270. Пространственно-временной уровень текста. Способы организации художественного времени 37 KB
  В нем всегда так или иначе присутствуют время и пространство. Важно понимать что художественное время и пространство – это не абстракции и даже не физические категории хотя и современная физика очень неоднозначно отвечает на вопрос что же такое время и пространство. Лессинг о чем мы уже говорили во второй главе а теоретики последних двух столетий особенно ХХ века доказали что художественное время и пространство не только значимый но зачастую определяющий компонент литературного произведения. В литературе время и пространство являются...
30271. Идейно-философский уровень текста. Понятия темы и идеи художественного произведения 35 KB
  Идейнотематический анализ выделяет в произведении основную центральную смысловую организацию материала под понятиями тема и идея. Если анализ действия пьесы изучает взаимосвязь событий и форму протекания действия то идейнотематический определяет смысл который наполняет эти действия; отвечает на вопрос почему это происходит. Он занимается поиском мотивов но мотивы если говорить более точно суть абстрактные и универсальные понятия по определению Пави а темы в отличие от них есть конкретизированные и индивидуализированные мотивы...
30272. Понятие метода литературоведения. Метод, методика, методология 33.5 KB
  Понятие метода литературоведения. Метод методика методология Все методы сформировались достаточно поздно в 19в.явля применяя методы определяемые как материалами исследования так и задачами стоящими перед исследователем. лит явления рассматривались как производные от соцх процессов ж психологический зформальный метод разработанный отечественными литературоведами Ю.
30273. Основные методы (школы) литературоведения. Общая характеристика 103 KB
  В Европе первые концепции искусства и литературы разработаны античными мыслителями. Платон в русле объективного идеализма обосновал собственно эстетические проблемы в том числе проблему прекрасного рассмотрел гносеологическую природу и воспитательную функцию искусства а также дал главные сведения по теории искусства и литературы прежде всего деление на роды эпос лирику и драму. В сочинениях Аристотеля Об искусстве поэзии Риторика и Метафизика при сохранении общеэстетического аспекта подхода к искусству происходит уже формирование...
30274. Основные методы (школы) литературоведения. Культурно-исторический метод 59 KB
  Основные методы школы литературоведения. Виднейший литературовед промышленной буржуазии Ипполит Тэн не случайно оказался связанным с целым рядом теоретиков работавших в самых различных областях науки. Автор Истории английской литры не отрицал огромного влияния на него социолога Бокля История английской цивилизации с его теорией расы и физической среды. Но больше всего на взглядах Тэна отразилось учение о происхождении видов Дарвина английского естествоиспытателя крого Тэн сочувственно цитировал в введении к указанному выше труду...
30275. Основные методы (школы) литературоведения. Сравнительно-исторический метод (компаративизм) 36 KB
  Основные методы школы литературоведения. Сравнительноисторический метод компаративизм Докторская диссертация знаменитого русского литературоведа академика А. Другой попыткой буржуазного литературоведения закрепиться на позитивистских позициях был сравнительноисторический компаративный метод. Практикуемый ими метод приводил их к подбору аналогичных сюжетов в литом творчестве соседних стран толкая их на исследование поэтической продукции прошлого.