Язык программирования C

Преобразование типов


Если в выражениях встречаются операнды различных типов, то они преобразуются к общему типу в соответствии с небольшим набором правил. В общем, автоматически производятся только преобразования, имеющие смысл, такие как, например, преобразование целого в плавающее в выражениях типа f+i. Выражения же, лишенные смысла, такие как использование переменной типа float в качестве индекса, запрещены.

Во-первых, типы char и int могут свободно смешиваться в арифметических выражениях: каждая переменная типа char автоматически преобразуется в int. Это обеспечивает значительную гибкость при проведении определеных преобразований символов. Примером может служить функция atoi, которая ставит в соответствие строке цифр ее численный эквивалент.

atoi(s) /* convert s to integer */ char s[]; { int i, n;

n = 0; for ( i = 0; s[i]>='0' && s[i]<='9'; ++i) n = 10 * n + s[i] - '0'; return(n); }

Kак уже обсуждалось в лекции №1, выражение

s[i] - '0'

имеет численное значение находящегося в s[i] символа, потому что значение символов '0', '1' и т.д. образуют возрастающую последовательность расположенных подряд целых положительных чисел.


char c; c = getchar(); if ( c == EOF) ...

На машине, которая не осуществляет знакового расширения, переменная 'с' всегда положительна, поскольку она описана как char, а так как EOF отрицательно, то условие никогда не выполняется. Чтобы избежать такой ситуации, мы всегда предусмотрительно использовали int вместо char для любой переменной, получающей значение от getchar.

Основная же причина использования int вместо char не связана с каким-либо вопросом о возможном знаковом расширении. просто функция getchar должна передавать все возможные символы (чтобы ее можно было использовать для произвольного ввода) и, кроме того, отличающееся значение EOF. Следовательно значение EOF не может быть представлено как char, а должно храниться как int.

Другой полезной формой автоматического преобразования типов является то, что выражения отношения, подобные i>j, и логические выражения, связанные операциями && и ||, по определению имеют значение 1, если они истинны, и 0, если они ложны. Таким образом, присваивание

isdigit = c >= '0' && c <= '9';

полагает isdigit равным 1, если с - цифра, и равным 0 в противном случае. (В проверочной части операторов if, while, for и т.д. "Истинно" просто означает "не нуль").

Неявные арифметические преобразования работают в основном, как и ожидается. В общих чертах, если операция типа + или *, которая связывает два операнда (бинарная операция), имеет операнды разных типов, то перед выполнением операции "низший" тип преобразуется к "высшему" и получается результат "высшего" типа. Более точно, к каждой арифметической операции применяется следующая последовательность правил преобразования.

  • типы char и short преобразуются в int, а float в double.
  • Затем, если один из операндов имеет тип double, то другой преобразуется в double, и результат имеет тип double.
  • В противном случае, если один из операндов имеет тип long, то другой преобразуется в long, и результат имеет тип long.
  • В противном случае, если один из операндов имеет тип unsigned, то другой преобразуется в unsigned и результат имеет тип unsigned.
  • В противном случае операнды должны быть типа int, и результат имеет тип int. Подчеркнем, что все переменные типа float в выражениях преобразуются в double; в "C" вся плавающая арифметика выполняется с двойной точностью.





Содержание раздела