Существует несколько схем для определения того, являются ли типы двух объектов эквивалентными. Две схемы, наиболее часто используемые, называются
Большинство реализаций языка Си используют схему
В операторах и выражениях должны использоваться переменные и константы только одного типа. Если все же мы смешиваем типы в одном выражении, то компилятор языка Си не считает программу неправильной, как это произошло бы при программировании на языке Паскаль. Вместо этого компилятор использует набор правил для автоматического преобразования типов. Это очень удобно, но может оказаться и опасным, особенно если мы допустили смешение типов нечаянно. Приведем несколько основных правил, касающихся преобразования типов:
double, float, long, int, short, char. Применение ключевого слова unsigned повышает ранг соответствующего типа данных со знаком.char может иметь целое значение 101, но не 22225.
Пример, приведенный ниже, иллюстрирует применение этих правил:
/*преобразования*/
int main( )
{
char ch;
int i;
float f1;
f1=i=ch='A'; /***8***/
printf("ch=%c,i=%d,f1=%2.2f\n",ch,i,f1);
ch=ch+1; /***10***/
i=f1=f1+2*ch; /***11***/
f1=2.0*ch+i; /***12***/
printf("ch=%c,i=%d,f1=%2.2f\n",ch,i,f1);
ch=2.0e30;/***14***/
printf("Теперь ch=%c\n",ch);
}
Выполнив программу "преобразования", получим следующие результаты:
ch=A,i=65,f1=65.00 ch=B,i=197,f1=329.00 Теперь ch=
Строки 8 и 9: величина ' A ' присваивается символьной переменной ch. Переменная i получает целое значение, являющееся преобразованием символа ' A ' в целое число, т.е. 65. Переменная f1 получает значение 65.00, являющееся преобразованием числа 65 в число с плавающей точкой.
Строки 10 и 13: значение символьной переменной ' A ' преобразуется в целое число 65, к которому затем добавляется 1. После этого получившееся в результате число 66 преобразуется в код символа В и помещается в переменную ch.
Строки 11 и 13: при умножении на 2 значение переменной ch преобразуется в целое число 66. При сложении с величиной переменной f1 получившееся в результате число 132 преобразуется в число с плавающей точкой. Результат 197.00 преобразуется в число целого типа и присваивается переменной i.
Строки 12 и 13: перед умножением на 2.0 значение переменной ch('B') преобразуется в число с плавающей точкой. Перед выполнением сложения величина переменной i(197) преобразуется в число с плавающей точкой, а результат 329.00 присваивается переменной f1.
Строки 14 и 15: здесь производится попытка осуществить преобразование типов в порядке убывания старшинства - переменная ch полагается равной сравнительно большому числу. Результаты оказываются неутешительными. Независимо от переполнения и усечения, которые имеют место, в итоге мы получили код, соответствующий какому-то непечатаемому знаку.
Существует еще один вид преобразования типов. Для сохранения точности вычислений при арифметических операциях все величины типа float преобразуются в данные типа double. Это существенно уменьшает ошибку округления. Конечный результат преобразуется обратно в число типа float, если это диктуется соответствующим оператором описания.
Самое лучшее - это вообще избегать преобразования типов, особенно в порядке убывания ранга. Но иногда оказывается удобным применять такие преобразования при условии, что мы ясно представляем смысл выполняемых действий. Преобразования типов, которые мы обсуждали до сих пор, выполнялись автоматически. Существует возможность точно указывать тип данных, к которому необходимо привести величину. Этот способ называется
(тип)
где фактическое имя требуемого типа представляется вместо слова тип.
Рассмотрим пример:
int nice; nice = 1.6+1.7; nice = (int)1.6+(int)1.7;
В первом примере используется автоматическое преобразование типов. Сначала числа 1.6 и 1.7 складываются - результат равен 3.3. Затем путем отбрасывания дробной части полученное число преобразуется в 3 для согласования с типом int переменной nice. Во втором примере 1.6 и 1.7 преобразуются в целые числа 1, так что переменной nice присваивается значение, равное 1+1, или 2.
Особенности работы с языком Си. Мы не должны смешивать типы; вот почему в некоторых языках это запрещено. Но бывают ситуации, когда это оказывается полезным. Философия языка Си заключается в том, чтобы не устанавливать барьеров на вашем пути, но при этом возложить на вас всю ответственность за злоупотребление предоставленной свободой.
Неявные преобразования типа выполняются главным образом для согласования аргументов оператора или функции (если это возможно) со значениями, предполагаемыми в этих операторах или функциях. Все неявные преобразования типа, которые могут встретиться, перечислены ниже (слева указывается преобразуемый тип, а справа - список типов, в которые он может быть преобразован):
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.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.
Можно отметить, что синтаксис типов в языке Си нерегулярен и беспорядочен, о чем свидетельствуют:
Существует несколько схем для определения того, являются ли типы двух объектов эквивалентными. Две схемы, наиболее часто используемые, называются
Большинство реализаций языка Си используют схему
В операторах и выражениях должны использоваться переменные и константы только одного типа. Если все же мы смешиваем типы в одном выражении, то компилятор языка Си не считает программу неправильной, как это произошло бы при программировании на языке Паскаль. Вместо этого компилятор использует набор правил для автоматического преобразования типов. Это очень удобно, но может оказаться и опасным, особенно если мы допустили смешение типов нечаянно. Приведем несколько основных правил, касающихся преобразования типов:
double, float, long, int, short, char. Применение ключевого слова unsigned повышает ранг соответствующего типа данных со знаком.char может иметь целое значение 101, но не 22225.
Пример, приведенный ниже, иллюстрирует применение этих правил:
/*преобразования*/
int main( )
{
char ch;
int i;
float f1;
f1=i=ch='A'; /***8***/
printf("ch=%c,i=%d,f1=%2.2f\n",ch,i,f1);
ch=ch+1; /***10***/
i=f1=f1+2*ch; /***11***/
f1=2.0*ch+i; /***12***/
printf("ch=%c,i=%d,f1=%2.2f\n",ch,i,f1);
ch=2.0e30;/***14***/
printf("Теперь ch=%c\n",ch);
}
Выполнив программу "преобразования", получим следующие результаты:
ch=A,i=65,f1=65.00 ch=B,i=197,f1=329.00 Теперь ch=
Строки 8 и 9: величина ' A ' присваивается символьной переменной ch. Переменная i получает целое значение, являющееся преобразованием символа ' A ' в целое число, т.е. 65. Переменная f1 получает значение 65.00, являющееся преобразованием числа 65 в число с плавающей точкой.
Строки 10 и 13: значение символьной переменной ' A ' преобразуется в целое число 65, к которому затем добавляется 1. После этого получившееся в результате число 66 преобразуется в код символа В и помещается в переменную ch.
Строки 11 и 13: при умножении на 2 значение переменной ch преобразуется в целое число 66. При сложении с величиной переменной f1 получившееся в результате число 132 преобразуется в число с плавающей точкой. Результат 197.00 преобразуется в число целого типа и присваивается переменной i.
Строки 12 и 13: перед умножением на 2.0 значение переменной ch('B') преобразуется в число с плавающей точкой. Перед выполнением сложения величина переменной i(197) преобразуется в число с плавающей точкой, а результат 329.00 присваивается переменной f1.
Строки 14 и 15: здесь производится попытка осуществить преобразование типов в порядке убывания старшинства - переменная ch полагается равной сравнительно большому числу. Результаты оказываются неутешительными. Независимо от переполнения и усечения, которые имеют место, в итоге мы получили код, соответствующий какому-то непечатаемому знаку.
Существует еще один вид преобразования типов. Для сохранения точности вычислений при арифметических операциях все величины типа float преобразуются в данные типа double. Это существенно уменьшает ошибку округления. Конечный результат преобразуется обратно в число типа float, если это диктуется соответствующим оператором описания.
Самое лучшее - это вообще избегать преобразования типов, особенно в порядке убывания ранга. Но иногда оказывается удобным применять такие преобразования при условии, что мы ясно представляем смысл выполняемых действий. Преобразования типов, которые мы обсуждали до сих пор, выполнялись автоматически. Существует возможность точно указывать тип данных, к которому необходимо привести величину. Этот способ называется
(тип)
где фактическое имя требуемого типа представляется вместо слова тип.
Рассмотрим пример:
int nice; nice = 1.6+1.7; nice = (int)1.6+(int)1.7;
В первом примере используется автоматическое преобразование типов. Сначала числа 1.6 и 1.7 складываются - результат равен 3.3. Затем путем отбрасывания дробной части полученное число преобразуется в 3 для согласования с типом int переменной nice. Во втором примере 1.6 и 1.7 преобразуются в целые числа 1, так что переменной nice присваивается значение, равное 1+1, или 2.
Особенности работы с языком Си. Мы не должны смешивать типы; вот почему в некоторых языках это запрещено. Но бывают ситуации, когда это оказывается полезным. Философия языка Си заключается в том, чтобы не устанавливать барьеров на вашем пути, но при этом возложить на вас всю ответственность за злоупотребление предоставленной свободой.
Неявные преобразования типа выполняются главным образом для согласования аргументов оператора или функции (если это возможно) со значениями, предполагаемыми в этих операторах или функциях. Все неявные преобразования типа, которые могут встретиться, перечислены ниже (слева указывается преобразуемый тип, а справа - список типов, в которые он может быть преобразован):
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.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.
Можно отметить, что синтаксис типов в языке Си нерегулярен и беспорядочен, о чем свидетельствуют:
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.