мета-данные страницы
  •  

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
c:c_ultimate_guide:operators [2025/10/09 13:16] – создано radi0devc:c_ultimate_guide:operators [2025/11/09 12:07] (текущий) – внешнее изменение A User Not Logged in
Строка 35: Строка 35:
 Унарный оператор:  Унарный оператор: 
   * ''!'' - не   * ''!'' - не
 +
 +===== Операторы присвоения =====
 +
 +
 +представляют из себя сокрашенные выражения
 +
 +++++список|
 +
 +  * ''+='' - присваивание после сложения. Присваивает левому операнду сумму левого и правого операндов: 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
 +++++
 +
 +===== Операторы сдвига =====
 +
 +Каждое целое число в памяти представлено в виде определенного количества разрядов. И операции сдвига позволяют сдвинуть битовое представление числа на несколько разрядов вправо или влево. Операции сдвига применяются __только к целочисленным__ операндам.
 +
 +  * ''<<'' - Сдвигает битовое представление числа, представленного первым операндом, влево на определенное количество разрядов, которое задается вторым операндом.
 +  * ''>>'' - Сдвигает битовое представление числа вправо на определенное количество разрядов.
 +
 +<code c>
 +int a = 2 << 2;  // 0b10 на два разрядов влево = 0b1000 = 8
 +int b = 16 >> 3; // 0b10000 на три разряда вправо = 0b10 = 2
 +</code>
 +
 +===== Поразрядные операции =====
 +
 +Поразрядные операции также проводятся только над разрядами __целочисленных__ операндов.
 +
 +  * ''&'' - поразрядная **конъюнкция** (операция И или поразрядное умножение). Возвращает 1, если оба из соответствующих разрядов обоих чисел равны 1
 +  * ''|'' - поразрядная **дизъюнкция** (операция ИЛИ или поразрядное сложение). Возвращает 1, если хотя бы один из соответствующих разрядов обоих чисел равен 1
 +  * ''^'' - поразрядное исключающее ИЛИ. Возвращает 1, если только один из соответствующих разрядов обоих чисел равен 1
 +  * ''~'' - поразрядное отрицание. Инвертирует все разряды операнда. Если разряд равен 1, то он становится равен 0, а если он равен 0, то он получает значение 1.
 +
 +<code c>
 +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
 +</code>
  
 ===== Преобразования типов ===== ===== Преобразования типов =====
  
 +В ряде случаев преобразования сопровождаются потерей информации, например, когда числа большей разрядности (скажем размером 4 байт) получаем число меньшей разрядности (например, в 2 байта). Без потери информации проходят следующие цепочки преобразований:
 +
 +  * ''char -> short -> int -> long''
 +  * ''unsigned char -> unsigned short -> unsigned int -> unsigned long''
 +  * ''float -> double -> long double''
 +
 +++++пример потери данных|
 +<code c>
 +#include <stdio.h>
 +  
 +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;
 +}
 +</code>
 +
 +Число 300 в двоичной системе = 0000000100101100, оставляем только первый младший байт: 00101100, и у нас получается число 44 в десятичной системе.
 +++++
 +
 +==== Неявное преобразование ====
 +
 +Преобразования, применяемые компилятором при арифметических операциях:
 +
 +  - Если один из операндов имеет тип long double, то второй операнд тоже будет преобразован в тип long double
 +  - Если предыдущий пункт не выполняется и если один из операндов имеет тип double, то второй операнд тоже будет преобразован к типу double
 +  - Если предыдущий пункт не выполняется и если один из операндов имеет тип float, то второй операнд тоже будет преобразован к типу float
 +  - Если предыдущий пункт не выполняется и если один из операндов имеет тип unsigned long int, то второй операнд тоже будет преобразован к типу unsigned long int
 +  - Если предыдущий пункт не выполняется и если один из операндов имеет тип long, то второй операнд тоже будет преобразован к типу long
 +  - Если предыдущий пункт не выполняется и если один из операндов имеет тип unsigned, то второй операнд тоже будет преобразован к типу unsigned
 +  - Если предыдущий пункт не выполняется то оба операнда приводятся к типу int
 +
 +==== Явное преобразование ====
 +
 +Явное преобразование происходит через операторы преобразования:
 +<code c>
 +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
 +</code>
  
 +===== Приоритет и очередность =====
 +^ Операторы ^ Выполняются ^
 +|%% () [] -> . %%| слева направо |
 +|%% ! ~ ++ -- + - * & (тип) sizeof %%| справа налево |
 +|%% * / % %%| слева направо |
 +|%% + - %%| слева направо |
 +|%% << >> %%| слева направо |
 +|%% < <= > >= %%| слева направо |
 +|%% == != %%| слева направо |
 +|%% & %%| слева направо |
 +|%% ^ %%| слева направо |
 +|%% | %%| слева направо |
 +|%% && %%| слева направо |
 +|%% || %%| слева направо |
 +|%% ?: %%| справа налево |
 +|%% = += -= *= /= %= &= ^= |= <<= >>= %%| справа налево |
 +|%% , %%| слева направо |
  
 +<note>
 +Примечание. Унарные операторы +, -, * и & имеют более высокий приоритет, чем те же бинарные
 +операторы.
 +</note>