Выражения в операторах языка программирования C-51
Выражением называется комбинация знаков операций и операндов, результатом которой является определенное значение. Знаки операций определяют действия, которые должны быть выполнены над операндами. Каждый операнд в выражении в свою очередь может быть выражением. Значение выражения зависит от расположения знаков операций и круглых скобок в выражении, а также от приоритета выполнения операций. Примеры выражений:
А+В A*(B+C)-(D-E)/F
Выражение в языке программирования С-51 состоит из операндов, которые комбинируются при помощи различных арифметических или логических операций, а также операций отношения. Над переменными-указателями возможно проведение адресных операций.
Операндом в выражении может быть переменная, числовая константа, подпрограмма-функция или указатель. Любой операнд, который имеет константное значение, называется константным выражением. Каждый операнд имеет тип.
Если в качестве операнда используется константа, то ему соответствует значение и тип представляющей его константы. Целая константа может быть типа int, long, unsigned int, unsigned long, в зависимости от ее значения и от формы записи. Символьная константа имеет тип int. Константа с плавающей точкой всегда имеет тип float.
При вычислении выражений тип каждого операнда может быть преобразован к другому типу. Преобразования типов могут быть неявными, при выполнении операций и вызовов функций, или явными, при выполнении операций приведения типов. Из за того, что неявные преобразования типов могут различаться для трансляторов разных фирм, то при написании программы лучше использовать явное преобразование типов переменных. Примеры явных преобразований типов операндов:
a=(int)b+(int)c; //Переменные a и b могут быть восьмиразрядными. Преобразование типов нужно чтобы избежать переполнения s=sin((float)a/15)); //Если не преобразовать тип переменной a, то деление будет целочисленным и результат деления будет равен нулю.
В выражениях в качестве операндов могут использоваться подвыражения. Подвыражение - это обычное выражение, заключенное в скобки. Подвыражения могут использоваться для группировки частей выражения, точно так же, как и в обычной алгебраической записи. Использование подвыражений позволяет сократить количество операторов в программе, а значит и объем исходного текста программы (но не объём исполняемой программы), но затрудняет отладку этой программы.
В языке программирования C-51 используются арифметические операции, результат которых зависит от типа операндов:
- + суммирование
- - вычитание
- * умножение
- / деление
- % вычисление остатка от целочисленного деления
Примеры выражений, использующие арифметические операции:
А+В А+В-С A*T+F/D A*(B+C)-(D-E)/F
В языке программирования C-51 также определено несколько одноместных арифметических операций:
- '-' изменение знака операнда на противоположное значение
- '+' знак плюс не влияет на значение операнда
- ++ увеличение значения операнда на единицу
- -- уменьшение значения операнда на единицу
Для одноместной операции требуется один операнд, которому она предшествует. Например:
P3 = -5; //Присвоить порту P3 значение числа -5 a = -b; //Присвоить переменной a отрицательное значение переменной b с=++a + 2; //Увеличить значение переменной a на 1 и прибавить 2 с=a++ + 2; //Прибавить к переменной a 2, присвоить это значение переменной c и только после этого увеличить значение переменной a на 1.
Над операндами можно осуществлять логические операции:
- '&&' логическое "и"
- '&' побитовое логическое "и"
- '||' логическое "или"
- '|' побитовое логическое "или"
- '^' "исключающее или" (суммирование по модулю два)
Здесь следует объяснить различие между логическими и побитовыми логическими операциями. Дело в том, что в стандартном языке ANSI C не существует битовых переменных. Для хранения битовых значений истина '1' и ложь '0' используются стандартные целые типы переменных. В простейшем случае это байт. При этом все значения переменной, отличающиеся от 0 считаются 1. Например, пусть в переменной a хранится число 5, а в переменной b - число 6. Тогда:
a|b=7 //00000101 or 00000110 = 00000111 a||b=1 //(00000101)->1 (00000110)->1; (1 or 1= 1), Результат равен 00000001 a&b=4 //00000101 and 00000110 = 00000100 a&&b=1 //(00000101)->1 (00000110)->1; (1 and 1= 1), Результат равен 00000001 a^b=3 //00000101 xor 00000110 = 00000011
В языке программирования C-51 также определено несколько одноместных логических операций:
- '!' инверсия операнда
- '~' побитовая инверсия операнда
Например, пусть в переменной a хранится число 5. Тогда:
a=~a; //~00000101 = 11111010 = 250 a=~a; //~11111010 = 00000101 = 5 a=!a; //(00000101)->1; ~1 = 0 a=!a; // ~0 = 1
В условном операторе и операторах цикла используются операции отношения:
- < меньше
- > больше
- <= меньше или равно
- >= больше или равно
- == равно
- != не равно
Если указанное отношение между операндами верно, то результат равен 1, иначе 0. Например, если d=7, то:
(d > 5) результат будет 1 (истина) (d = 4) результат будет 0 (ложь)
Над переменными-указателями возможно проведение адресных операций.
- '*' операция косвенной адресации
- '&' вычисление адреса переменной
Операция косвенной адресации '*' осуществляет доступ к переменной при помощи указателя. Результатом операции является значение переменной, на которую указывает операнд. Типом результата является тип переменной, адресуемой указателем. При работе с указателями необходимо быть предельно осторожными, так как, если указатель содержит недопустимый адрес, то результат операции чтения или записи будет непредсказуем и может привести к выходу проектируемого устройства из строя.
Операция вычисления адреса переменной '&' дает адрес ячейки памяти своего операнда. Операндом может быть любой идентификатор. Имя функции или массива также может быть операндом операции вычисления адреса переменной, хотя в этом случае знак операции вычисления адреса переменной является лишним, так как имена массивов и функций являются и так являются адресами. Операция вычисления адреса переменной не может применятся к элементам структуры, являющимися полями битов, и к объектам с классом памяти register.
Пример использования адресных операций при работе с указателем:
int t, f=0, *adress; adress = &t /* переменной adress, объявленной как указатель, присваивается адрес переменной t */ *adress =f; /* переменной находящейся по адресу, содержащемуся в переменной adress, присваивается значение переменной f, т.е. 0, что эквивалентно t=f; т.е. t=0; */
Может возникнуть вопрос: а зачем тогда нужны указатели, если можно прекрасно обойтись обычным присваиванием переменной? Использование указателей очень удобно при написании подпрограмм. Ведь одни и те же действия подпрограмма должна выполнять над различными участками памяти. Например при выводе информации через последовательный порт:
void PutNadp(char code *c)//Объявлен указатель c на символ в памяти программ {do{while(!TI); //Подождать готовности последовательного порта TI=0; SBUF=*c++; //Передать очередной символ }while(*c!=0); //Если передан последний символ строки } //то выйти из подпрограммы ... PutNadp("привет!"); //Вывод одной строки ... PutNadp("Вася!"); //Вывод второй строки
Приоритеты выполнения операций.
В языке С-51 операции с высшими приоритетами вычисляются первыми. Наивысшим приоритетом является приоритет равный 1. Приоритеты и порядок операций приведены в табл. 1. Порядок вычисления выражения следующий: сначала выполняются операторы в круглых скобках, в них от старшего приоритета к младшему, а среди равнозначных операторов - слева направо.
Таблица 1
Приоритет | Знак операции | Типы операции | Порядок выполнения |
---|---|---|---|
2 | () [] . -> | Выражение | Слева направо |
1 | - ~ ! * & ++ -- sizeof приведение типов | Унарные | Справа налево |
3 | * / % | Мультипликативные | Слева направо |
4 | + - | Аддитивные | |
5 | << >> | Сдвиг | |
6 | < > <= >= | Отношение | |
7 | == != | Отношение (равенство) | |
8 | & | Поразрядное И | |
9 | ^ | Поразрядное исключающее ИЛИ | |
10 | | | Поразрядное ИЛИ | |
11 | && | Логическое И | |
12 | || | Логическое ИЛИ | |
13 | ? : | Условная | |
14 | = *= /= %= += -= &= |= >>= <<= ^= | Простое и составное присваивание | Справа налево |
15 | , | Последовательное вычисление | Слева направо |
[Назад] [Содержание] [Вперёд]