- •лекция 4
- •План лекции
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Выражения и подвыражения
- •Классы, приоритеты и ассоциативность операций
- •Классы, приоритеты и ассоциативность операций
- •Приоритеты операций в
- •Приоритеты операций в
- •Приоритеты операций в языке Си
- •Выражения и подвыражения
- •Выражения l-value
- •Выражения l-value
- •Выражения l-value
- •Выражения l-value
- •Точки следования, побочные эффекты
- •Точки следования, побочные эффекты
- •Точки следования, побочные эффекты
- •Точки следования, побочные эффекты
- •Точки следования, побочные эффекты
- •Точки следования, побочные эффекты
- •Неявные преобразования типов
- •Неявные преобразования
- •Неявные преобразования чисел
- •Неявные преобразования чисел
- •Неявные преобразования чисел
- •Неявные преобразования чисел
- •Неявные преобразования указателей
- •Неявные преобразования указателей
- •Неявные преобразования указателей
- •Явные преобразования указателей
- •Заключение
Неявные преобразования типов
Над числами
Над указателями
Других нет
Неявные преобразования
Есличиселкакой-либо из аргументов имеет тип 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
Подробно о каждом преобразовании см. след. слайды
Неявные преобразования чисел
Целочисленное повышение
Значения типов enum, signed char, short int, unsigned char, unsigned short int автоматически преобразуются в int (если значение представимо как int) или в unsigned int (в противном случае)
Для всех известных компиляторов enum, char, short int представимы как int
Неявные преобразования чисел
Целочисленные преобразования из типа со знаком ST в тип без знака UT
Если sizeof(ST) == sizeof(UT), то битовое представление не меняется
Если sizeof(ST) < sizeof(UT), то битовое представление со знаком дополняется старшими нулями
Если sizeof(ST) > sizeof(UT), то старшие разряды отбрасываются
Целочисленные преобразования из типа без знака UT в тип со знаком ST
Если sizeof(ST) >= sizeof(UT), то битовое представление не меняется
Если sizeof(ST) < sizeof(UT), то результат зависит от компилятора
Неявные преобразования чисел
Преобразования целые <--> числа с плавающей точкой
С плавающей точкой --> целое
Дробная часть отбрасывается
int x = (int)1.25; // x == 1
Если полученное значение выходит из диапазона целого типа, то результат неопределен
int x = (int)1e20; // рез-т неопределён
Целое --> с плавающей точкой
Если целое входит в диапазон типа с плавающей, но представляется неточно, то одно из двух ближайших значений с плавающей
Если выходит из диапазона типа с плавающей, то результат неопределен
Неявные преобразования чисел
Преобразования чисел с плавающей точкой из типа F1 в F2
Если sizeof(F1) <= sizeof(F2), то значение не меняется (но может измениться битовое представление)
Если sizeof(F1) > sizeof(F2) и входит в диапазон F2, то одно из двух ближайших значений
Если sizeof(F1) > sizeof(F2) и не входит в диапазон F2, то неопределено
Неявные преобразования указателей
В операциях присваивания и сравнения целочисленное константное выражение со значением 0 автоматически преобразуется в указатель любого типа
Результатом преобразования 0 в указатель является NULL, отличный от всех остальных указателей
NULL не соответствует ни одной ячейке памяти
Неявные преобразования указателей
В операциях присваивания и сравнения указатель на значение типа T автоматически преобразуется в указатель на значение типа const T и на значение типа volatile T
Неявные преобразования указателей
Указатель типа void * автоматически преобразуется к указателю любого типа
Если результат подвергнуть явному обратному преобразованию, то мы получим прежний указатель
Значение типа функция автоматически преобразуется к типу указатель на функцию
Значение типа указатель на функцию автоматически преобразуется к типу функция
Явные преобразования указателей
Для указателей допускаются и другие преобразования, но в связи с ними возникает проблема зависимости результата от реализации. Эти преобразования должны быть специфицированы явным оператором преобразования типа или оператором приведения
Указатель можно привести к целочисленному типу, достаточно большому для его хранения; требуемый размер зависит от реализации. Функция преобразования также зависит от реализации
Объект целочисленного типа можно явно преобразовать в указатель. Если целое получено из указателя и имеет достаточно большой размер, это преобразование даст тот же указатель; в противном случае результат зависит от реализации
Указатель на один тип можно преобразовать в указатель на другой тип. Если исходный указатель ссылается на объект, должным образом не выровненный по границам слов памяти, то в результате может произойти ошибка адресации. Если требования на выравнивание у нового типа меньше или совпадают с требованиями на выравнивание первоначального типа, то гарантируется, что преобразование указателя в другой тип и обратно его не изменит; понятие "выравнивание" зависит от реализации, однако в любой реализации объекты типа char предъявляют минимальные требования на выравнивание.
Указатель может быть преобразован в другой указатель того же типа с добавлением или удалением квалификаторов того типа объекта, на который этот указатель показывает. Новый указатель, полученный добавлением квалификатора, имеет то же значение, но с дополнительными ограничениями, внесенными новыми квалификаторами. Операция по удалению квалификатора у объекта приводит к тому, что восстанавливается действие его начальных квалификаторов, заданных в объявлении этого объекта.
Наконец, указатель на функцию может быть преобразован в указатель на функцию другого типа. Вызов функции по преобразованному указателю зависит от реализации; однако, если указатель еще раз преобразовать к его исходному типу, результат будет идентичен вызову по первоначальному указателю.
