Приведение типов - это изменение (преобразование) типа объекта. Приведение типов используется для преобразования объектов одного скалярного типа в другой скалярный тип. Для выполнения преобразования необходимо перед объектом записать в скобках нужный тип:
'(' Имя типа ')' Операнд.
Пример использования функции приведения типов при вычислении выражений:
int i;
float x;
х = (float)i+2.0;
В этом примере переменная целого типа i с помощью операции приведения типов приводится к плавающему типу, и только затем участвует в вычислении выражения.
Константное выражение - это выражение, результатом которого является константа. Операндом константного выражения могут быть целые константы, символьные константы, константы с плавающей точкой, константы перечисления, выражения приведения типов, выражения с операцией sizeof и другие константные выражения. Однако на использование знаков операций в константных выражениях налагаются следующие ограничения:
1. В константных выражениях нельзя использовать операции присваивания и последовательного вычисления (,).
2. Операция "адрес" (&) может быть использована только при инициализации.
Выражения со знаками операций могут участвовать в выражениях как операнды. Выражения со знаками операций могут быть унарными (с одним операндом), бинарными (с двумя операндами) и тернарными (с тремя операндами).
Унарное выражение состоит из операнда и предшествующего ему знака унарной операции и имеет следующий формат:
Знак унарной операции Операнд
Бинарное выражение состоит из двух операндов, разделенных знаком бинарной операции:
Операнд1 Знак бинарной операции Операнд2
Тернарное выражение состоит из трех операндов, разделенных знаками тернарной операции ('?' и ':')> и имеет формат:
Операнд1 '?' Операнд2 ':' ОперандЗ.
Операции. По количеству операндов, участвующих в операции, операции подразделяются на унарные, бинарные и тернарные.
В языке С-51 имеются следующие унарные операции, приведенные в табл. 9.8.

Унарные операции выполняются справа налево.
Операции инкремента и декремента увеличивают или уменьшают значение операнда на единицу и могут быть записаны как справа, так и слева от операнда. Если знак операции записан перед операндом (префиксная форма), то изменение операнда происходит до его использования в выражении. Если знак операции записан после операнда (постфиксная форма), то операнд вначале используется в выражении, а затем происходит его изменение.
В отличие от унарных, бинарные операции, список которых приведен в табл. 9.9, выполняются слева направо.


Левый операнд операции присваивания должен быть выражением, ссылающимся на область памяти (но не идентификатором, объявленным с ключевым словом const). Левый операнд не может также быть массивом.
При записи выражений следует помнить, что символы '*', '&', '-' '+' могут обозначать как унарную, так и бинарную операцию.
Преобразования типов при вычислении выражений
При выполнении операций производится автоматическое преобразование типов, чтобы привести операнды выражений к общему типу или чтобы расширить короткие величины до размера целых величин, используемых в машинных командах. Выполнение преобразования типов зависит от специфики операций и от типа операнда или операндов.
Рассмотрим общие арифметические преобразования.
1. Если один операнд имеет тип float, то второй также преобразуется к типу float.
2. Если один операнд имеет тип unsigned long, то и второй также преобразуется к типу unsigned long.
3. Если один операнд имеет тип long, то второй также преобразуется к типу long.
4. Если один операнд имеет тип unsigned int, то второй операнд преобразуется к этому же типу.
Таким образом, можно отметить, что при вычислении выражений операнды преобразуются к типу того операнда, который имеет наибольший размер. Приведем пример преобразования типов при вычислении математического выражения:
float ft,sd;
unsigned char ch;
unsigned long in;
int i;
....
sd=ft*(i+ch/in);
При выполнении оператора присваивания правила преобразования будут использоваться следующим образом. Операнд ch преобразуется к unsigned long. По этому же правилу i преобразуется к unsigned long и результат операции, заключенной в круглые скобки, будет иметь тип unsigned long. Затем он преобразуется к типу float, и результат всего выражения будет иметь тип float.
Операции унарного минуса, логического и поразрядного отрицания
Арифметическая операция унарного минуса (-) меняет знак своего операнда. Операнд должен быть целой или плавающей величиной. При выполнении осуществляются обычные арифметические преобразования.
Пример:

Операция логического отрицания (!) вырабатывает значение 0, если операнд имеет не нулевое значение, и значение 1, если операнд равен нулю (0). Результат имеет тип int. Операнд должен быть целого или плавающего типа или типа указатель.
Пример:
int t, z=0;
t=!z;
Переменная t получит значение, равное 1, т. к. переменная z имела значение, равное 0.
Операция поразрядного отрицания (-) инвертирует каждый бит операнда.
Операнд должен быть целого типа. Пример:
char b = 9;
char f;
f = ~b;
Двоичное значение 9 равно 00001001. В результате операции ~b будет получено двоичное значение 11110110.
Операции разадресации и вычисления адреса
Эти операции используются для работы с переменными типа указатель.
Операция разадресации ('*') позволяет осуществить доступ к переменной при помощи указателя. Операнд операции разадресации обязательно должен быть указателем. Результатом операции является значение переменной, на которую указывает операнд. Типом результата является тип переменной, на которую ссылается указатель.
В отличие от прямого использования переменных использование указа- указателей может приводить к непредсказуемым результатам. Результат не определен, если указатель содержит недопустимый адрес.
Рассмотрим типичные ситуации, когда указатель содержит недопустимый адрес:
- указатель является нулевым;
- указатель определяет адрес такого объекта, который не является активным в момент использования указателя;
- указатель определяет адрес, который не выровнен до типа объекта, на который он указывает;
- указатель определяет адрес, не используемый выполняющейся программой.
Операция вычисления адреса переменной (&) возвращает адрес своего операнда. Операндом может быть любой идентификатор. Имя функции или массива также может быть операндом операции "адрес", хотя в этом случае применение знака '&' является лишним, т. к. имена массивов и функций изначально являются адресами.
Операция & не может применяться к элементам структуры, являющимся полями битов, т. к. эти элементы не выровнены по байтам. Кроме того, эта операция не может быть применена к объектам с классом памяти register.
Примеры:
int t, //Объявляется переменная целого типа t
f=0, //Объявляется переменная f и ей присваивается 0
*adress; //Объявляется указатель на переменные целого типа
adress = &t // указателю adress присваивается адрес переменной t
*adress =f; /* переменной, находящейся по адресу, содержащемуся в переменной adress, т.е. переменной t, присваивается значение переменной f, т.е. 0, что эквивалентно оператору t=f; */
Операция sizeof
С помощью операции sizeof можно определить размер области памяти, которая соответствует идентификатору или типу переменной. Операция sizeof записывается в следующем виде:
"sizeof ("Выражение') '
В качестве выражения может быть использован любой идентификатор, либо имя типа, заключенное в скобки. Отметим, что не может быть использовано имя типа void, а идентификатор не может относиться к полю битов структуры или быть именем функции.