====== операторы ====== ===== Арифметические операторы ===== Бинарными((т.е. с двумя операндами)) арифметическими операторами являются ''+'', ''-'', ''*'', ''/'', а также оператор деления по модулю ''%''. Деление целых сопровождается отбрасыванием дробной части, какой бы она ни была. Оператор ''%'' к операндам типов float и double не применяется. В какую сторону (в сторону увеличения или уменьшения числа) будет усечена дробная часть при выполнении ''/'' и каким будет знак результата операции ''%'' с отрицательными операндами, зависит от машины. ===== Операторы отношения и логические операторы ===== Операторами отношения являются: * ''>'' - больше * ''>='' - больше или равно * ''<'' - меньше * ''<='' - меньше или равно Операторы сравнения на равенство: * ''=='' - равно * ''!='' - не равно Логические операторы: * ''&&'' - или * ''||'' - и Выражения, между которыми стоят операторы ''&&'' или ''||'', вычисляются слева направо. Вычисление прекращается, как только становится известна истинность или ложность результата Унарный оператор: * ''!'' - не ===== Операторы присвоения ===== представляют из себя сокрашенные выражения ++++список| * ''+='' - присваивание после сложения. Присваивает левому операнду сумму левого и правого операндов: A += B эквивалентно A = A + B * ''-='' - присваивание после вычитания. Присваивает левому операнду разность левого и правого операндов: A -= B эквивалентно A = A - B * ''*='' - присваивание после умножения. Присваивает левому операнду произведение левого и правого операндов: A *= B эквивалентно A = A * B * ''/='' - присваивание после деления. Присваивает левому операнду частное левого и правого операндов: A /= B эквивалентно A = A / B * ''%='' - присваивание после деления по модулю. Присваивает левому операнду остаток от целочисленного деления левого операнда на правый: A %= B эквивалентно A = A % B * ''<<='' - присваивание после сдвига разрядов влево. Присваивает левому операнду результат сдвига его битового представления влево на определенное количество разрядов, равное значению правого операнда: A <<= B эквивалентно A = A << B * ''>>='' - присваивание после сдвига разрядов вправо. Присваивает левому операнду результат сдвига его битового представления вправо на определенное количество разрядов, равное значению правого операнда: A >>= B эквивалентно A = A >> B * ''&='' - присваивание после поразрядной конъюнкции. Присваивает левому операнду результат поразрядной конъюнкции его битового представления с битовым представлением правого операнда: A &= B эквивалентно A = A & B * ''|='' - присваивание после поразрядной дизъюнкции. Присваивает левому операнду результат поразрядной дизъюнкции его битового представления с битовым представлением правого операнда: A |= B эквивалентно A = A | B * ''^='' - присваивание после операции исключающего ИЛИ. Присваивает левому операнду результат операции исключающего ИЛИ его битового представления с битовым представлением правого операнда: A ^= B эквивалентно A = A ^ B ++++ ===== Операторы сдвига ===== Каждое целое число в памяти представлено в виде определенного количества разрядов. И операции сдвига позволяют сдвинуть битовое представление числа на несколько разрядов вправо или влево. Операции сдвига применяются __только к целочисленным__ операндам. * ''<<'' - Сдвигает битовое представление числа, представленного первым операндом, влево на определенное количество разрядов, которое задается вторым операндом. * ''>>'' - Сдвигает битовое представление числа вправо на определенное количество разрядов. int a = 2 << 2; // 0b10 на два разрядов влево = 0b1000 = 8 int b = 16 >> 3; // 0b10000 на три разряда вправо = 0b10 = 2 ===== Поразрядные операции ===== Поразрядные операции также проводятся только над разрядами __целочисленных__ операндов. * ''&'' - поразрядная **конъюнкция** (операция И или поразрядное умножение). Возвращает 1, если оба из соответствующих разрядов обоих чисел равны 1 * ''|'' - поразрядная **дизъюнкция** (операция ИЛИ или поразрядное сложение). Возвращает 1, если хотя бы один из соответствующих разрядов обоих чисел равен 1 * ''^'' - поразрядное исключающее ИЛИ. Возвращает 1, если только один из соответствующих разрядов обоих чисел равен 1 * ''~'' - поразрядное отрицание. Инвертирует все разряды операнда. Если разряд равен 1, то он становится равен 0, а если он равен 0, то он получает значение 1. int a = 5 | 2; // 0b101 | 0b010 = 0b111 = 7 int b = 6 & 2; // 0b110 & 0b010 = 0b10 = 2 int c = 5 ^ 2; // 0b101 ^ 0b010 = 0b111 = 7 int f = 12; // 0b00001100 int d = ~f; // 0b11110011 или -13 ===== Преобразования типов ===== В ряде случаев преобразования сопровождаются потерей информации, например, когда числа большей разрядности (скажем размером 4 байт) получаем число меньшей разрядности (например, в 2 байта). Без потери информации проходят следующие цепочки преобразований: * ''char -> short -> int -> long'' * ''unsigned char -> unsigned short -> unsigned int -> unsigned long'' * ''float -> double -> long double'' ++++пример потери данных| #include int main(void){ int number1 = 300; char code = number1; // потеря точности - число number1 усекается до 1 байта printf("code = %d \n", code); // code = 44 short number2 = 100000; // потеря точности - число 100000 усекается до 2 байт printf("number2 = %d \n", number2); // number2 = -31072 return 0; } Число 300 в двоичной системе = 0000000100101100, оставляем только первый младший байт: 00101100, и у нас получается число 44 в десятичной системе. ++++ ==== Неявное преобразование ==== Преобразования, применяемые компилятором при арифметических операциях: - Если один из операндов имеет тип long double, то второй операнд тоже будет преобразован в тип long double - Если предыдущий пункт не выполняется и если один из операндов имеет тип double, то второй операнд тоже будет преобразован к типу double - Если предыдущий пункт не выполняется и если один из операндов имеет тип float, то второй операнд тоже будет преобразован к типу float - Если предыдущий пункт не выполняется и если один из операндов имеет тип unsigned long int, то второй операнд тоже будет преобразован к типу unsigned long int - Если предыдущий пункт не выполняется и если один из операндов имеет тип long, то второй операнд тоже будет преобразован к типу long - Если предыдущий пункт не выполняется и если один из операндов имеет тип unsigned, то второй операнд тоже будет преобразован к типу unsigned - Если предыдущий пункт не выполняется то оба операнда приводятся к типу int ==== Явное преобразование ==== Явное преобразование происходит через операторы преобразования: int a = 10; int b = 4; int c = a / b; double d = a / b; double e = (double)a / (double)b; printf("c = %d \n", c); // 2 printf("d = %f \n", d); // 2.00000 printf("e = %f \n", e); // 2.50000 int number = 70; char symbol = (char) number; printf("symbol = %c \n", symbol); // F printf("symbol (int code) = %d \n", symbol); // 70 ===== Приоритет и очередность ===== ^ Операторы ^ Выполняются ^ |%% () [] -> . %%| слева направо | |%% ! ~ ++ -- + - * & (тип) sizeof %%| справа налево | |%% * / % %%| слева направо | |%% + - %%| слева направо | |%% << >> %%| слева направо | |%% < <= > >= %%| слева направо | |%% == != %%| слева направо | |%% & %%| слева направо | |%% ^ %%| слева направо | |%% | %%| слева направо | |%% && %%| слева направо | |%% || %%| слева направо | |%% ?: %%| справа налево | |%% = += -= *= /= %= &= ^= |= <<= >>= %%| справа налево | |%% , %%| слева направо | Примечание. Унарные операторы +, -, * и & имеют более высокий приоритет, чем те же бинарные операторы.