Неявное преобразование типа
Неявные преобразования типа выполняются главным образом для согласования аргументов оператора или функции (если это возможно) со значениями, предполагаемыми в этих операторах или функциях. Все неявные преобразования типа, которые могут встретиться, перечислены ниже (слева указывается преобразуемый тип, а справа - список типов, в которые он может быть преобразован):
char - int, short int, long int (Преобразование к значению с большим числом двоичных разрядов может включать, а может не включать расширение знакового разряда - это зависит от реализации языка. Для элементов заданного набора знаков гарантируется преобразование в неотрицательные целые значения).
int - char, short int, long int ( преобразование к целому большей длины включает расширение знакового разряда. Преобразование к целому меньшей длины вызывает отбрасывание лишних старших разрядов). float, double, unsigned int(интерпретация комбинации битов в виде беззнакового целого значения).
short int - аналогично типу int.
long int - аналогично типу int.
float - double, int, short int, long int (машинно-зависимое преобразование, если преобразуемое значение слишком велико, то результат неопределен).
double - float (преобразование с округлением и последующим отбрасыванием лишних разрядов), int, short int, long int.
Арифметические преобразования
Арифметические операторы языка Си преобразуют операнды к соответствующим типам автоматически, если операнды не имели таких типов с самого начала. Схема преобразования, используемая этими операторами, называется обычно арифметические преобразования ; эта схема может быть описана следующими правилами:
- Преобразовать операнды типов char и short int к типу int ; преобразовать операнды типа float к типу double.
- Если хотя бы один из операндов имеет тип double, то и другой операнд преобразуется к типу double (если он другого типа); результат имеет тип double.
- Если хотя бы один операнд имеет тип long, то и другой операнд преобразуется к типу long (если он другого типа); результат имеет тип long.
- Если хотя бы один из операндов имеет тип unsigned, то и другой операнд преобразуется к типу unsigned (если его тип не unsigned); результат имеет тип unsigned.
- Если ни один из случаев 1-4 не имеет места, то оба операнда должны иметь тип int ; такой же тип будет и у результата.
Явные преобразования типов
Выражения могут быть преобразованы из одного типа в другой явным указанием. Выражение E может быть явно преобразовано к типу имя-типа с помощью записи вида
где имя типа представляется в форме
указатель-типа абстрактный-описатель
Абстрактный описатель аналогичен описателю, за исключением того, что он не содержит определяемого или описываемого идентификатора. Смысл слов имя-типа, представляемого в форме
где Т является указателем типа, может быть определен одним из таких способов:
- форма абстрактного описателя - смысл слов " Т абстрактный описатель ";
- пустой ( абстрактный описатель ) - абстрактный описатель типа Т ;
- * ( абстрактный описатель ) - указатель на тип Т ;
- абстрактный описатель ( ) - функция, возвращающая значение типа Т ;
- абстрактный описатель [ n ] - массив с n элементами типа Т, n - выражение с постоянным значением;
Приведем примеры явного преобразования. Предположим, что даны следующие определения и описания:
int i;
char *pc, *name;
char *calloc( ), *strcpy( );
тогда можно привести следующие примеры явных преобразований типов:
(char) i - преобразует значение типа int в значение типа char.
pc=(char *) 0777 - преобразует восьмеричный литер 0777 в значение указателя на знак таким образом, что оно может быть присвоено переменной "pc".
(emp *) calloc(1,sizeof(emp)) - преобразует значение "знакового" указателя, возвращаемого функцией calloc, в значениеуказателя emp.
(void) strcpy(name,"gehani") - опускает значение, возвращенное функцией strcpy.
Синтаксис типов
Можно отметить, что синтаксис типов в языке Си нерегулярен и беспорядочен, о чем свидетельствуют:
- Трудность создания форматеров.
- Большое число ошибок, допускаемых даже опытными программистами.
- Трудность создания синтаксических анализаторов для трансляторов с языка Си - не существует двух трансляторов с языка Си, синтаксис входного языка для которых полностью совпадал бы.
- Имеется три случая, когда необходимо использовать типы:
- описания, связывающие тип с именем, как например, в случае описания (глобальных) переменных и формальных параметров;
- описания, связывающие значения (и тип) с именем, как, например, описания программ;
- приведения, обеспечивающие, например, возможность трактовки символов как целых.
|