Выражения языка С презентация

Содержание

Слайд 2

План лекции Классы, приоритеты и ассоциативность операций языка Си Выражения

План лекции

Классы, приоритеты и ассоциативность операций языка Си
Выражения l-value
Порядок вычисления выражений,

точки следования, побочные эффекты
Выражения и подвыражения
Неявные преобразования типов
Слайд 3

Обзор операций языка Си 1/3 Операции Си делятся на 5

Обзор операций языка Си 1/3

Операции Си делятся на 5 классов по

числу и расположению аргументов
Запись одной операции состоит из одной или нескольких лексем
Слайд 4

Обзор операций языка Си 2/3 Операции связываются с аргументами по

Обзор операций языка Си 2/3

Операции связываются с аргументами по возрастанию своих

приоритетов
Приоритеты задаются целыми числами
Слайд 5

Обзор операций языка Си 3/3 Ассоциативность бинарных операций задает расстановку

Обзор операций языка Си 3/3

Ассоциативность бинарных операций задает расстановку скобок в

выражениях, содержащих операции одного приоритета
Левоассоциативные -- слева направо
Правоассоциативные -- справа налево
Операции языка Си одного приоритета имеют одинаковую ассоциативность
Иначе расстановка скобок неоднозначна
Слайд 6

Приоритеты операций в языке Си

Приоритеты операций в языке Си

Слайд 7

Приоритеты операций в языке Си

Приоритеты операций в языке Си

Слайд 8

Приоритеты операций в языке Си

Приоритеты операций в языке Си

Слайд 9

Первичные выражения Идентификатор переменной или функции Константа Строковый литерал (является lvalue) Выражение, взятое в круглые скобки

Первичные выражения

Идентификатор переменной или функции
Константа
Строковый литерал (является lvalue)
Выражение, взятое в круглые

скобки
Слайд 10

Доступ к элементу массива A[k] A

Доступ к элементу массива

A[k]
A

Слайд 11

Выражения и подвыражения ::= | ',' ::= | ::= '='

Выражения и подвыражения

<выражение>::=
<выражение-присваивания>
| <выражение> ',' <выражение-присваивания>
<выражение-присваивания> ::=
<условное-выражение>
| <унарное-выражение> <оператор-присваивания> <выражение-присваивания>
<оператор-присваивания>::= '='

| '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
Слайд 12

Выражения и подвыражения ::= | '?' ':' ::= ::= | '||'

Выражения и подвыражения

<условное-выражение> ::=
<логическое-ИЛИ-выражение>
| <логическое-ИЛИ-выражение> '?' <выражение> ':' <условное-выражение>
<константное-выражение> ::= <условное-выражение>
<логическое-ИЛИ-выражение>::=
<логическое-И-выражение>
| <логическое-ИЛИ-выражение> '||' <логическое-И-выражение>

Слайд 13

Выражения и подвыражения ::= | '&&' ::= | '|' ::= | '^'

Выражения и подвыражения

<логическое-И-выражение>::= <ИЛИ-выражение> | <логическое-И-выражение> '&&' <ИЛИ-выражение>
<ИЛИ-выражение>::= <исключающее-ИЛИ-выражение> | <ИЛИ-выражение> '|' <исключающее-ИЛИ-выражение>
<исключающее-ИЛИ-выражение>::= <И-выражение> | <исключающее-ИЛИ-выражение> '^' <И-выражение>

Слайд 14

Выражения и подвыражения ::= | '&' ::= | '==' | '!='

Выражения и подвыражения

<И-выражение>::= <выражение-равенства> | <И-выражение> '&' <выражение-равенства>
<выражение-равенства>::= <выражение-отношения> | <выражение-равенства> '==' <выражение-отношения> | <выражение-равенства> '!=' <выражение-отношения>

Слайд 15

Выражения и подвыражения ::= | ' | '>' | '

Выражения и подвыражения

<выражение-отношения>::= <сдвиговое-выражение> | <выражение-отношения> '<' <сдвиговое-выражение> | <выражение-отношения> '>' <сдвиговое-выражение> | <выражение-отношения> '<=' <сдвиговое-выражение> | <выражение-отношения> '>=' <сдвиговое-выражение>

x >> 2
x <

y < z << 2
(x < y) < (z << 2)
Слайд 16

Выражения и подвыражения ::= | '>>' | ' ::= |

Выражения и подвыражения

<сдвиговое-выражение>::= <аддитивное-выражение> | <сдвиговое-выражение> '>>' <аддитивное-выражение> | <сдвиговое-выражение> '<<' <аддитивное-выражение>
<аддитивное-выражение>::= <мультипликативное-выражение> | <аддитивное-выражение> '+' <мультипликативное-выражение> | <аддитивное-выражение> '-' <мультипликативное-выражение>

x

+ y
x >> y+z
x << (y+z)
x * y x + y + z
x - y - z
Слайд 17

Выражения и подвыражения ::= | '*' | '/' | '%'

Выражения и подвыражения

<мультипликативное-выражение>::= <выражение-приведенное-к-типу> | <мультипликативное-выражение> '*' <выражение-приведенное-к-типу> | <мультипликативное-выражение> '/' <выражение-приведенное-к-типу> | <мулътипликативное-выражение> '%' <выражение-приведенное-к-типу>

(double)x
x * y
(x / y)

/ z
x % y
Слайд 18

Выражения и подвыражения ::= | '(' ')' ::= | '++'

Выражения и подвыражения

<выражение-приведенное-к-типу>::= <унарное-выражение> | '(' <имя-типа> ')' <выражение-приведенное-к-типу> <унарное-выражение>::= <постфиксное-выражение> | '++' <унарное-выражение> | '--' <унарное-выражение> | <унарный-оператор> <выражение-приведенное-к-типу> | 'sizeof' <унарное-выражение> | 'sizeof' '(' <имя-типа>

')'
<унарный-оператор>::= '&' | '*' | '+' | '-' | '~' | '!'

&x
(int*) &x
x++
++(x--)
--(x++)
* (int*) &x
sizeof(x)
sizeof(int)

Слайд 19

Выражения и подвыражения ::= | '[' ']' | '(' [

Выражения и подвыражения

<постфиксное-выражение>::= <первичное-выражение> | <постфиксное-выражение> '[' <выражение> ']' | <постфиксное-выражение> '(' [<список-аргументов-выражений>] ')' | <постфиксное-выражение> '.' <идентификатор> | <постфиксное-выражение>

'->' <идентификатор> | <постфиксное-выражение> '++' | <постфиксное-выражение> '--'

x
A[x]
f (x, y)
point.x
point->x
i++
i--

Слайд 20

Выражения и подвыражения ::= | | | '(' ')' x 1.25f "ABCDEF" (x+y)

Выражения и подвыражения

<первичное-выражение>::= <идентификатор> | <константа> | <строка> | '(' <выражение> ')'

x
1.25f
"ABCDEF"
(x+y)

Слайд 21

Выражения и подвыражения ::= | | |

Выражения и подвыражения

<константа>::= <целая-константа> | <символьная-константа> | <константа-с-плавающей-точкой> | <константа-перечисление>

Слайд 22

Выражения и подвыражения ::= | ','

Выражения и подвыражения

<список-аргументов-выражений>::=
<выражение-присваивания> | <список-аргументов-выражений> ',' <выражение-присваивания>

Слайд 23

Выражения и подвыражения Классы, приоритеты и ассоциативность операций языка Си

Выражения и подвыражения
Классы, приоритеты и ассоциативность операций языка Си
Далее
Выражения l-value
Порядок вычисления

выражений, точки следования, побочные эффекты
Неявные преобразования типов
Слайд 24

Выражения l-value Ошибка или нет: (A[i] A[ A[i] Выражения языка

Выражения l-value

Ошибка или нет:
(A[i] < A[j] ? A[i] : A[j]) =

1 // min(A[i], A[j]) заменить на 1
A[ A[i] < A[j] ? i : j ] = 1
Выражения языка Си, значениям которых гарантированно соответствует ячейка памяти, называются l-value
Значениям, которые хранятся только в регистрах процессора, не соответствует никакая ячейка памяти
Только 5 видов выражений в языке Си являются l-value – см. след. слайд
Остальные виды выражений – не l-value
Слайд 25

Выражения l-value l-value получаются при следующих операциях Доступ к значению

Выражения l-value

l-value получаются при следующих операциях
Доступ к значению переменной
Доступ через указатель

*
Доступ к элементу массива a[k]
Доступ к полю структуры или объединения student.name
Доступ к полю структуры или объединения через указатель pstudent->name
Все остальные операции дают выражения, не являющиеся l-value
Слайд 26

Выражения l-value Операции, требующие l-value Левый аргумент во всех видах

Выражения l-value

Операции, требующие l-value
Левый аргумент во всех видах присваивания =, +=

и т.п.
Взятие адреса &
Префиксные и постфиксные ++ и --
Слайд 27

Выражения l-value Пример 1 int x; x = 2; //

Выражения l-value

Пример 1
int x; x = 2; // x – l-value int

A[10]; A[5] = 5+x; // A[5] – l-value, 5+x – не l-value
Пример 2
int x, y; (x < y ? x : y) = 1; // ошибка, т.к. (x < y ? x : y) не l-value *(x < y ? &x : &y) = 1; // ОК, т.к. *(x < y ? &x : &y) – l-value
Пример 3
(A[i] < A[j] ? A[i] : A[j]) = 1; // ошибка A[ A[i] < A[j] ? i : j ] = 1; // ОК
Слайд 28

Точки следования, побочные эффекты Побочный эффект вычисления выражения – это

Точки следования, побочные эффекты

Побочный эффект вычисления выражения – это факт изменения

содержимого ячеек памяти в процессе вычисления выражения
Присваивание
x = 1;
Сложный побочный эффект
i = 0; A[i++] = i++; // чему равно i – 0 или 1?
В каком порядке выполнятся = и ++?
Слайд 29

Точки следования, побочные эффекты Точка следования (sequence point) -- точка

Точки следования, побочные эффекты

Точка следования (sequence point) -- точка программы, в

которой гарантируется, что все побочные эффекты предыдущих вычислений уже проявились, а побочные эффекты последующих ещё отсутствуют
Слайд 30

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

Точки следования, побочные эффекты

Между вычислением левого и правого аргументов в операциях

&&, || и , (запятая)
Между вычислением первого и второго или третьего аргументов в операции ?:
В конце всего выражения
Перед входом в вызываемую функцию
В объявлении с инициализацией на момент завершения вычисления инициализирующего значения
В остальном порядок выполнения операций определяет компилятор
Слайд 31

Точки следования, побочные эффекты Пример 1 while (*p++ != 0

Точки следования, побочные эффекты

Пример 1
while (*p++ != 0 && *q++ !=

0) *p = *q;
Все побочные эффекты *p++ != 0 проявятся до начала вычисления *q++ != 0
Правило 1
Все побочные эффекты *p++ != 0 и *q++ != 0 проявятся до начала вычисления *p = *q
Правило 3
Что делает этот цикл while?
Слайд 32

Точки следования, побочные эффекты Пример 2 int A[3] = {1,0,2},

Точки следования, побочные эффекты

Пример 2
int A[3] = {1,0,2}, *p = A;
int

a = (*p++) ? (*p++) : 0; // чему равно a?
Точка следования находится после первого *p++
p уже увеличена на 1 при вычислении второго *p++
Слайд 33

Точки следования, побочные эффекты Пример 3 int i = 0,

Точки следования, побочные эффекты

Пример 3
int i = 0, j = i++,

k = i++;
int x = f(i++) + g(j++) + h(k++);
Каждая из переменных i, j и k принимает новое значение перед входом в f, g и h соответственно
Порядок вызова функций f(), g(), h() неопределён
Порядок инкремента i, j, k неопределён
Если i, j и k – глобальные переменные, то значения j и k неопределены внутри f, значения i и k неопределены внутри g, значения i и j неопределены внутри h
Слайд 34

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

Неявные преобразования типов

Над числами
Над указателями
Других нет

Слайд 35

Неявные преобразования чисел Если какой-либо из аргументов имеет тип long

Неявные преобразования чисел

Если какой-либо из аргументов имеет тип long double, то

другой приводится к long double
В противном случае, если какой-либо из аргументов имеет тип double, то другой приводится к double
В противном случае, если какой-либо из аргументов имеет тип float, то другой приводится к float
В противном случае для обоих аргументов осуществляется целочисленное повышение; затем, если один из аргументов имеет тип unsigned long int, той другой преобразуется в unsigned long int
В противном случае, если один из аргументов принадлежит типу long int, а другой -- unsigned int, то результат зависит от того, покрывает ли long int все значения unsigned int
Если это так, то unsigned int приводится к long int
Если нет, то оба аргумента преобразуются в unsigned long int
В противном случае, если один из аргументов имеет тип long int, то другой приводится к long int
В противном случае, если один из аргументов -- unsigned int, то другой приводится к unsigned int
В противном случае оба аргумента имеют тип int
Подробно о каждом преобразовании см. след. слайды
Слайд 36

Неявные преобразования чисел Целочисленное повышение Значения типов enum, signed char,

Неявные преобразования чисел

Целочисленное повышение
Значения типов enum, signed char, short int, unsigned

char, unsigned short int автоматически преобразуются в int (если значение представимо как int) или в unsigned int (в противном случае)
Для всех известных компиляторов enum, char, short int представимы как int
Слайд 37

Неявные преобразования чисел Целочисленные преобразования из типа со знаком ST

Неявные преобразования чисел

Целочисленные преобразования из типа со знаком ST в тип

без знака UT
Если sizeof(ST) == sizeof(UT), то битовое представление не меняется
Если sizeof(ST) < sizeof(UT), то битовое представление со знаком дополняется старшими нулями
Если sizeof(ST) > sizeof(UT), то старшие разряды отбрасываются
Целочисленные преобразования из типа без знака UT в тип со знаком ST
Если sizeof(ST) >= sizeof(UT), то битовое представление не меняется
Если sizeof(ST) < sizeof(UT), то результат зависит от компилятора
Слайд 38

Неявные преобразования чисел Преобразования целые числа с плавающей точкой С

Неявные преобразования чисел

Преобразования целые <--> числа с плавающей точкой
С плавающей точкой

--> целое
Дробная часть отбрасывается
int x = (int)1.25; // x == 1
Если полученное значение выходит из диапазона целого типа, то результат неопределен
int x = (int)1e20; // рез-т неопределён
Целое --> с плавающей точкой
Если целое входит в диапазон типа с плавающей, но представляется неточно, то одно из двух ближайших значений с плавающей
Если выходит из диапазона типа с плавающей, то результат неопределен
Слайд 39

Неявные преобразования чисел Преобразования чисел с плавающей точкой из типа

Неявные преобразования чисел

Преобразования чисел с плавающей точкой из типа F1 в

F2
Если sizeof(F1) <= sizeof(F2), то значение не меняется (но может измениться битовое представление)
Если sizeof(F1) > sizeof(F2) и входит в диапазон F2, то одно из двух ближайших значений
Если sizeof(F1) > sizeof(F2) и не входит в диапазон F2, то неопределено
Слайд 40

Неявные преобразования указателей В операциях присваивания и сравнения целочисленное константное

Неявные преобразования указателей

В операциях присваивания и сравнения целочисленное константное выражение со

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

Неявные преобразования указателей В операциях присваивания и сравнения указатель на

Неявные преобразования указателей

В операциях присваивания и сравнения указатель на значение типа

T автоматически преобразуется в указатель на значение типа const T и на значение типа volatile T
Слайд 42

Неявные преобразования указателей Указатель типа void * автоматически преобразуется к

Неявные преобразования указателей

Указатель типа void * автоматически преобразуется к указателю любого

типа
Если результат подвергнуть явному обратному преобразованию, то мы получим прежний указатель
Значение типа функция автоматически преобразуется к типу указатель на функцию
Значение типа указатель на функцию автоматически преобразуется к типу функция
Слайд 43

Явные преобразования указателей Для указателей допускаются и другие преобразования, но

Явные преобразования указателей

Для указателей допускаются и другие преобразования, но в связи

с ними возникает проблема зависимости результата от реализации. Эти преобразования должны быть специфицированы явным оператором преобразования типа или оператором приведения
Указатель можно привести к целочисленному типу, достаточно большому для его хранения; требуемый размер зависит от реализации. Функция преобразования также зависит от реализации
Объект целочисленного типа можно явно преобразовать в указатель. Если целое получено из указателя и имеет достаточно большой размер, это преобразование даст тот же указатель; в противном случае результат зависит от реализации
Указатель на один тип можно преобразовать в указатель на другой тип. Если исходный указатель ссылается на объект, должным образом не выровненный по границам слов памяти, то в результате может произойти ошибка адресации. Если требования на выравнивание у нового типа меньше или совпадают с требованиями на выравнивание первоначального типа, то гарантируется, что преобразование указателя в другой тип и обратно его не изменит; понятие "выравнивание" зависит от реализации, однако в любой реализации объекты типа char предъявляют минимальные требования на выравнивание.
Указатель может быть преобразован в другой указатель того же типа с добавлением или удалением квалификаторов того типа объекта, на который этот указатель показывает. Новый указатель, полученный добавлением квалификатора, имеет то же значение, но с дополнительными ограничениями, внесенными новыми квалификаторами. Операция по удалению квалификатора у объекта приводит к тому, что восстанавливается действие его начальных квалификаторов, заданных в объявлении этого объекта.
Наконец, указатель на функцию может быть преобразован в указатель на функцию другого типа. Вызов функции по преобразованному указателю зависит от реализации; однако, если указатель еще раз преобразовать к его исходному типу, результат будет идентичен вызову по первоначальному указателю.
Имя файла: Выражения-языка-С.pptx
Количество просмотров: 26
Количество скачиваний: 0