Операторы и выражения в C: от деления до побитовых операций с примерами

Разбираем все группы операторов языка C: арифметику, присваивание, сравнение, логику, биты, тернарный оператор и sizeof.

Показываем, почему 17 / 5 даёт 3, -7 % 2 равно −1, а выражение flags & 4 == 4 проверяет совсем другой бит.

Все примеры скомпилированы в GCC 13.3 и Clang 17, вывод взят из терминала.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 2872 статьи автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3526 экспертных мнений Подписаться на Телеграм-канал
Обложка: Операторы и выражения в C: от деления до побитовых операций с примерами

Операторы в C — это знаки, которыми программа считает, сравнивает и меняет значения: +, %, ==, &&, <<, ?: и ещё три десятка. Оператор вместе с операндами образует выражение, например a % b == 0. Ниже разбираем все группы операторов языка Си с примерами и таблицей приоритета, а заодно три места, где новички ошибаются чаще всего: целочисленное деление, остаток от деления отрицательных чисел и выражения без скобок.

Каждая программа в статье скомпилирована дважды, в GCC 13.3 на Ubuntu 24.04 и в Apple clang 17 на macOS, вывод скопирован из терминала. Компилятора ещё нет? Начните с инструкции как выбрать и установить компилятор C. Если вы пришли из Python, сравните с разбором операторов Python: знаки похожи, а поведение местами отличается.

CheckroiCheckroiПодборка курсов по C (язык Си)15 курсов • 6 школСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Какие операторы есть в языке C

Рой разбирает операторы языка C у монитора

Сводная таблица групп. Подробности по каждой ниже.

Группа Операторы Пример
Арифметические + - * / % total = price * count;
Присваивание = += -= *= /= %= <<= >>= &= ^= |= sum += x;
Инкремент и декремент ++ -- i++;
Сравнение == != < > <= >= if (age >= 18)
Логические && || ! if (ok && !error)
Побитовые & | ^ ~ << >> flags |= FLAG_READ;
Условный (тернарный) ?: max = a > b ? a : b;
Прочие sizeof, (тип), ,, & и * для адресов, . и -> n = sizeof arr / sizeof arr[0];

Одни и те же знаки иногда означают разное. Звёздочка между двумя числами умножает, а перед указателем достаёт значение по адресу. Амперсанд между числами даёт побитовое И, а перед переменной возвращает её адрес. Компилятор различает их по числу операндов: унарный оператор берёт один, бинарный два, тернарный ?: три.

Почти весь этот набор без изменений перешёл в C++, Java, C# и JavaScript, поэтому таблица пригодится и после C. Как связаны эти языки, рассказывали в обзоре языков семейства C.

Арифметические операторы и деление в C

Сложение, вычитание и умножение работают как в школе. Сюрпризы начинаются на делении.

#include <stdio.h>

int main(void) {
    int a = 17, b = 5;

    printf("%d + %d = %d\n", a, b, a + b);
    printf("%d - %d = %d\n", a, b, a - b);
    printf("%d * %d = %d\n", a, b, a * b);
    printf("%d / %d = %d\n", a, b, a / b);
    printf("%d %% %d = %d\n", a, b, a % b);
    printf("%d / 5.0 = %.1f\n", a, a / 5.0);
    return 0;
}

Вывод:

17 + 5 = 22
17 - 5 = 12
17 * 5 = 85
17 / 5 = 3
17 % 5 = 2
17 / 5.0 = 3.4

Целочисленное деление

Если оба операнда целые, деление в C отбрасывает дробную часть: 17 / 5 даёт 3, а не 3,4. Округления нет, остаток просто теряется. Чтобы получить дробь, хотя бы один операнд должен быть вещественным: 17 / 5.0 или (double)a / b.

С отрицательными числами деление отбрасывает дробную часть в сторону нуля, поэтому -7 / 2 даёт −3, а не −4. Так требует стандарт начиная с C99, раньше направление выбирал компилятор (описание на cppreference).

Остаток от деления

Оператор % возвращает остаток от деления целых чисел. Стандарт связывает его с делением тождеством (a / b) * b + a % b == a, отсюда правило: знак остатка совпадает со знаком делимого.

#include <stdio.h>

int main(void) {
    printf("-7 / 2 = %d\n", -7 / 2);
    printf("-7 %% 2 = %d\n", -7 % 2);
    printf("7 %% -2 = %d\n", 7 % -2);

    int n = -7;
    int r = ((n % 3) + 3) % 3;   /* остаток всегда от 0 до 2 */
    printf("математический остаток -7 по 3 = %d\n", r);
    return 0;
}

Вывод:

-7 / 2 = -3
-7 % 2 = -1
7 % -2 = 1
математический остаток -7 по 3 = 2

Из-за этого проверка нечётности через n % 2 == 1 ломается на отрицательных числах. Для −3 остаток равен −1, и условие ложно:

#include <stdio.h>

int main(void) {
    int n = -3;
    printf("n %% 2 == 1 даёт %d\n", n % 2 == 1);
    printf("n %% 2 != 0 даёт %d\n", n % 2 != 0);
    return 0;
}

Вывод:

n % 2 == 1 даёт 0
n % 2 != 0 даёт 1

Решение: сравнивайте с нулём (n % 2 != 0), а если нужен остаток строго от 0 до b − 1, пишите ((n % b) + b) % b, как во втором примере.

Для типичных задач остаток незаменим. Так переводят секунды в часы и минуты:

#include <stdio.h>

int main(void) {
    for (int n = -3; n <= 3; n++) {
        printf("%2d: %s\n", n, (n % 2 == 0) ? "чётное" : "нечётное");
    }
    int seconds = 3725;
    printf("%d с = %d ч %d мин %d с\n", seconds,
           seconds / 3600, seconds % 3600 / 60, seconds % 60);
    return 0;
}

Вывод:

-3: нечётное
-2: чётное
-1: нечётное
 0: чётное
 1: нечётное
 2: чётное
 3: нечётное
3725 с = 1 ч 2 мин 5 с

Оператор % работает только с целыми типами. Попытка написать 7.5 % 2.0 не скомпилируется, остаток вещественных чисел считает функция fmod() из <math.h>. На Linux программу с ней собирают с флагом -lm:

#include <stdio.h>
#include <math.h>

int main(void) {
    double x = 7.5, y = 2.0;
    printf("fmod(7.5, 2.0) = %.1f\n", fmod(x, y));
    return 0;
}

Вывод:

fmod(7.5, 2.0) = 1.5

Деление на ноль и переполнение

  • Целое деление на ноль и % 0 — неопределённое поведение. Обычно программа падает, но гарантий нет.
  • INT_MIN / -1 тоже неопределённое поведение: результат не помещается в int.
  • Переполнение знакового целого (INT_MAX + 1) не определено стандартом. Беззнаковые типы, наоборот, переполняются по модулю, и это гарантировано. В Python целые растут без предела, поэтому эта ловушка обычно неожиданна для тех, кто пришёл из операторов Python.
#include <stdio.h>
#include <limits.h>

int main(void) {
    unsigned char c = 250;
    c += 10;
    printf("unsigned char 250 + 10 = %d\n", c);

    unsigned int u = UINT_MAX;
    u = u + 1;
    printf("UINT_MAX + 1 = %u\n", u);
    printf("INT_MAX = %d\n", INT_MAX);
    return 0;
}

Вывод:

unsigned char 250 + 10 = 4
UINT_MAX + 1 = 0
INT_MAX = 2147483647

В первой строке 260 не помещается в unsigned char (максимум 255), поэтому значение «прокрутилось» до 260 − 256 = 4.

Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Присваивание, инкремент и декремент

Простое присваивание = кладёт значение справа в переменную слева. Составные операторы сокращают запись: x += 3 значит x = x + 3. Такие пары есть для всех арифметических и побитовых операторов.

Присваивание в C само является выражением и возвращает записанное значение. Поэтому работает цепочка a = b = 0: она разбирается справа налево как a = (b = 0).

Префиксный и постфиксный инкремент

Оператор ++ увеличивает переменную на единицу, -- уменьшает. Разница между формами видна, только когда результат куда-то идёт:

  • i++ (постфиксный) возвращает старое значение, потом увеличивает;
  • ++i (префиксный) сначала увеличивает, потом возвращает новое.
#include <stdio.h>

int main(void) {
    int i = 5;
    int a = i++;   /* a получает 5, потом i становится 6 */
    int b = ++i;   /* i становится 7, b получает 7 */
    printf("a = %d, b = %d, i = %d\n", a, b, i);

    int x = 10;
    x += 3;   /* 13 */
    x *= 2;   /* 26 */
    x %= 7;   /* 5 */
    x <<= 2;  /* 20 */
    printf("x = %d\n", x);
    return 0;
}

Вывод:

a = 5, b = 7, i = 7
x = 20

Отдельной строкой i++; и ++i; ничем не отличаются, пишите как привыкли. Чаще всего инкремент встречается в заголовке цикла for, где счётчик растёт на каждом шаге; что такое шаг цикла, объясняли в статье что такое итерация.

Дважды изменять переменную в одном выражении нельзя

Выражения вроде i = i++ + 1 или a[i] = i++ меняют переменную и ещё раз меняют или читают её без точки следования между этими действиями. Стандарт называет это неопределённым поведением (C11, раздел 6.5, пункт 2, черновик стандарта N1570). Где именно в выражении стоят точки следования, перечислено в справке Microsoft о точках следования C.

#include <stdio.h>

int main(void) {
    int i = 1;
    i = i++ + 1;
    printf("%d\n", i);
    return 0;
}

Оба наших компилятора напечатали 2, но полагаться на это нельзя: другой компилятор или другой уровень оптимизации вправе выдать иное. Clang предупреждает о такой строке даже без флагов, GCC с флагом -Wall:

05_ub.c:5:7: warning: operation on 'i' may be undefined [-Wsequence-point]

Операторы сравнения и логические операторы

Операторы сравнения ==, !=, <, >, <=, >= возвращают int: 1, если условие верно, и 0, если нет. Отдельного логического типа в старом C не было, поэтому любое ненулевое значение считается истиной. Тип bool со значениями true и false подключается заголовком <stdbool.h> (с C99), а в C23 bool, true и false стали ключевыми словами и заголовок не нужен.

Логические операторы:

Оператор Название Результат 1, когда
&& логическое И оба операнда ненулевые
|| логическое ИЛИ хотя бы один операнд ненулевой
! логическое НЕ операнд равен нулю

Короткое вычисление

Операторы && и || вычисляют правую часть, только если без неё ответ неизвестен. У 0 && … результат уже ноль, у 1 || … уже единица, и вторая функция не вызывается:

#include <stdio.h>

int check(const char *name, int value) {
    printf("  вызвана %s\n", name);
    return value;
}

int main(void) {
    printf("5 > 3 даёт %d, 5 == 3 даёт %d\n", 5 > 3, 5 == 3);
    printf("!0 = %d, !42 = %d\n", !0, !42);

    printf("0 && ...:\n");
    if (check("левая", 0) && check("правая", 1)) { }
    printf("1 || ...:\n");
    if (check("левая", 1) || check("правая", 0)) { }
    return 0;
}

Вывод:

5 > 3 даёт 1, 5 == 3 даёт 0
!0 = 1, !42 = 0
0 && ...:
  вызвана левая
1 || ...:
  вызвана левая

Так защищаются от деления на ноль в одном условии: сначала проверка делителя, потом деление.

#include <stdio.h>

int main(void) {
    int total = 100, count = 0;
    if (count != 0 && total / count > 10) {
        printf("среднее больше 10\n");
    } else {
        printf("делить не стали: count = %d\n", count);
    }
    return 0;
}

Вывод:

делить не стали: count = 0

Сравнение дробных чисел

Числа double хранятся в двоичном виде с округлением, поэтому 0.1 + 0.2 == 0.3 ложно. Дробные значения сравнивают с допуском:

#include <stdio.h>
#include <math.h>

int main(void) {
    double s = 0.1 + 0.2;
    printf("0.1 + 0.2 == 0.3 даёт %d\n", s == 0.3);
    printf("разница меньше 1e-9: %d\n", fabs(s - 0.3) < 1e-9);
    return 0;
}

Вывод:

0.1 + 0.2 == 0.3 даёт 0
разница меньше 1e-9: 1

Побитовые операторы в C

Ряд переключателей-битов и маска на столе

Побитовые операторы работают с отдельными битами целого числа. Без них не обходится программирование микроконтроллеров, драйверов и сетевых протоколов: там один байт хранит восемь флагов, а регистр устройства настраивают масками. Чем занят программист микроконтроллеров, рассказывали отдельно.

Оператор Что делает 12 и 10 (1100 и 1010)
& И: бит 1, если 1 в обоих 8 (1000)
| ИЛИ: бит 1, если 1 хотя бы в одном 14 (1110)
^ исключающее ИЛИ: бит 1, если биты разные 6 (0110)
~ инверсия всех битов ~0u = 4294967295
<< сдвиг влево, умножение на степень двойки 12 << 1 = 24
>> сдвиг вправо, деление на степень двойки 12 >> 2 = 3

Типичный приём с флагами: |= включает бит, &= ~ выключает, ^= переключает, & проверяет.

#include <stdio.h>

#define FLAG_READ  (1u << 0)   /* 0001 */
#define FLAG_WRITE (1u << 1)   /* 0010 */
#define FLAG_EXEC  (1u << 2)   /* 0100 */

int main(void) {
    unsigned a = 12, b = 10;   /* 1100 и 1010 */
    printf("a & b  = %u\n", a & b);
    printf("a | b  = %u\n", a | b);
    printf("a ^ b  = %u\n", a ^ b);
    printf("a << 1 = %u\n", a << 1);
    printf("a >> 2 = %u\n", a >> 2);
    printf("~0u    = %u\n", ~0u);

    unsigned mode = 0;
    mode |= FLAG_READ | FLAG_WRITE;   /* включить два флага */
    mode &= ~FLAG_WRITE;              /* выключить запись */
    mode ^= FLAG_EXEC;                /* переключить исполнение */
    printf("mode = %u, чтение %s\n", mode, (mode & FLAG_READ) ? "есть" : "нет");
    return 0;
}

Вывод:

a & b  = 8
a | b  = 14
a ^ b  = 6
a << 1 = 24
a >> 2 = 3
~0u    = 4294967295
mode = 5, чтение есть

Для битовых операций берите беззнаковые типы. Сдвиг отрицательного числа влево — неопределённое поведение, а сдвиг вправо зависит от компилятора. Сдвиг на число бит, равное ширине типа или больше (1u << 32 для 32-битного unsigned), тоже не определён.

Не путайте & с &&. Выражение 2 & 1 даёт 0 (общих битов нет), а 2 && 1 даёт 1 (оба числа ненулевые).

Тернарный оператор, sizeof, приведение и запятая

Тернарный оператор условие ? a : b возвращает a, если условие истинно, иначе b. Удобен для коротких присваиваний, а ветвления с несколькими действиями читаются легче через if. В Python та же идея записывается словами, сравните с разбором тернарного оператора в Python.

sizeof возвращает размер типа или объекта в байтах, тип результата size_t, печатается через %zu. Классика: число элементов массива как sizeof arr / sizeof arr[0]. Внутри функции, куда массив передан параметром, этот приём не работает: там arr уже указатель.

Приведение типа (double)a меняет тип значения на время вычисления. Место скобок решает исход: (double)a / b делит дробно, а (double)(a / b) сначала делит нацело и только потом превращает 3 в 3.0.

Оператор «запятая» вычисляет выражения слева направо и возвращает последнее. Чаще всего он встречается в заголовке цикла с двумя счётчиками.

#include <stdio.h>

int main(void) {
    int age = 20;
    const char *status = (age >= 18) ? "взрослый" : "несовершеннолетний";
    printf("%s\n", status);

    int arr[10];
    printf("sizeof(int) = %zu, sizeof arr = %zu, элементов = %zu\n",
           sizeof(int), sizeof arr, sizeof arr / sizeof arr[0]);

    int a = 7, b = 2;
    printf("(double)a / b = %.1f\n", (double)a / b);
    printf("(double)(a / b) = %.1f\n", (double)(a / b));

    int i, j;
    for (i = 0, j = 10; i < j; i += 3, j -= 3) { }
    printf("i = %d, j = %d\n", i, j);
    return 0;
}

Вывод:

взрослый
sizeof(int) = 4, sizeof arr = 40, элементов = 10
(double)a / b = 3.5
(double)(a / b) = 3.0
i = 6, j = 4
Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Приоритет операций в C

Приоритет операций определяет, как компилятор расставит невидимые скобки. Чем выше строка, тем сильнее оператор связывает операнды. Таблица по справочнику cppreference:

Уровень Операторы Порядок
1 a++ a-- () [] . -> слева направо
2 ++a --a +a -a ! ~ (тип) *p &x sizeof _Alignof справа налево
3 * / % слева направо
4 + - слева направо
5 << >> слева направо
6 < <= > >= слева направо
7 == != слева направо
8 & слева направо
9 ^ слева направо
10 | слева направо
11 && слева направо
12 || слева направо
13 ?: справа налево
14 = += -= *= /= %= <<= >>= &= ^= |= справа налево
15 , слева направо

Порядок (ассоциативность) решает спор равных: a - b - c считается как (a - b) - c, а a = b = c как a = (b = c).

Три ловушки приоритета

  1. Побитовое И слабее сравнения. flags & 4 == 4 разбирается как flags & (4 == 4), то есть flags & 1.
  2. Сдвиг слабее сложения. 1 << 2 + 1 равно 1 << 3, то есть 8, а не 5.
  3. Постфиксный ++ сильнее разыменования. *p++ читает значение и сдвигает указатель. Чтобы увеличить само значение, пишут (*p)++.
#include <stdio.h>

int main(void) {
    unsigned flags = 6;   /* 0110 */
    if (flags & 4 == 4) printf("без скобок: флаг найден\n");
    else                printf("без скобок: флага нет\n");
    if ((flags & 4) == 4) printf("со скобками: флаг найден\n");

    int x = 1 << 2 + 1;   /* сначала 2 + 1, потом сдвиг */
    printf("1 << 2 + 1 = %d\n", x);

    int arr[] = {10, 20, 30};
    int *p = arr;
    int v = *p++;         /* берёт arr[0], потом сдвигает указатель */
    printf("v = %d, теперь *p = %d\n", v, *p);
    return 0;
}

Вывод:

без скобок: флага нет
со скобками: флаг найден
1 << 2 + 1 = 8
v = 10, теперь *p = 20

Оба компилятора с -Wall предупреждают о первых двух строках. GCC пишет так:

09_prec.c:5:15: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
09_prec.c:9:15: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]

Правило на практике простое: таблицу помнить не обязательно, достаточно ставить скобки везде, где смешиваются побитовые, логические и арифметические операторы.

И ещё одно: приоритет говорит, как сгруппировать выражение, но не в каком порядке вычислять операнды. В f() + g() компилятор вправе вызвать g() первой. Порядок гарантирован только у &&, ||, ?: и запятой, так это описано и в справке Microsoft по приоритету и порядку вычисления. Запятая между аргументами функции служит простым разделителем и порядок вычисления не задаёт.

Неявные преобразования типов в выражениях

Если в выражении встречаются разные типы, C приводит их к общему по «обычным арифметическим преобразованиям»: int с double даёт double, char и short перед вычислением расширяются до int. Опаснее всего смесь знакового и беззнакового целого: знаковое превращается в беззнаковое, и −1 становится огромным числом.

#include <stdio.h>

int main(void) {
    int n = -1;
    unsigned int u = 1;
    if (n < u) printf("-1 < 1\n");
    else       printf("-1 >= 1u: n превратилось в %u\n", (unsigned)n);
    return 0;
}

Вывод:

-1 >= 1u: n превратилось в 4294967295

Такая ошибка часто прячется в циклах, где счётчик int сравнивают с результатом strlen() или sizeof (оба size_t). В C оба компилятора предупреждают об этом только с флагом -Wextra, одного -Wall мало (проверили на GCC 13.3 и Clang 17):

11_unsigned.c:6:11: warning: comparison of integer expressions of different signedness: 'int' and 'unsigned int' [-Wsign-compare]

Частые ошибки с операторами и что с ними делать

Рой радуется, что выражение со скобками посчиталось верно
  1. = вместо == в условии. if (errors = 5) присваивает пятёрку и всегда идёт в ветку. Решение: собирайте с -Wall, GCC ответит suggest parentheses around assignment used as truth value.
  2. Целочисленное деление там, где нужна дробь. double avg = sum / count; при целых sum и count теряет дробную часть до присваивания. Решение: (double)sum / count.
  3. Проверка нечётности через % 2 == 1. На отрицательных числах остаток равен −1. Решение: n % 2 != 0.
  4. Скобки при смешении &, |, << со сравнением и арифметикой. Решение: ставить скобки всегда, даже если вы уверены в приоритете.
  5. Изменение и повторное использование одной переменной в выражении. i = i++ + 1, a[i] = i++ и подобное. Решение: разнести на две строки.
  6. Сравнение int с unsigned и size_t. Решение: счётчик цикла делать size_t и включать -Wextra.

Четыре ошибки из шести (первую, четвёртую, пятую и шестую) ловит компилятор, если включить предупреждения: gcc -Wall -Wextra main.c. Целочисленное деление и проверку % 2 == 1 он пропускает, их находят тестами. Список того, что входит в каждый флаг, есть в документации GCC.

Где освоить язык C системно

Операторы и выражения проходят в начале почти любого курса по C, сразу после первой программы. Дальше идут функции, указатели, массивы и работа с памятью, а там без проверки заданий и разбора кода новички застревают надолго.

Ниже курсы по языку Си из нашего каталога, полный список с ценами собран на странице курсов по C. Если интересует разработка игр или высоконагруженных систем, посмотрите курсы C++: операторы там те же плюс перегрузка.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Инженер-программист
Перейти на сайт курса
GeekBrainsGeekBrains159 408 ₽4428 ₽/мес.12 месяцевОбзор курса
Специалист по информационной безопасности: расширенный курс
Перейти на сайт курса
НетологияНетология117 300 ₽4018 ₽/мес.13 месяцевОбзор курса
Внедрение и работа в DevSecOps
Перейти на сайт курса
OTUSOTUS88 000 ₽8800 ₽/мес.5 месяцевОбзор курса
Блокчейн
Перейти на сайт курса
GeekBrainsGeekBrains168 768 ₽4153 ₽/мес.4 месяцаОбзор курса
Инженер-программист C++
Перейти на сайт курса
GeekBrainsGeekBrains7970 ₽221 ₽/мес.1 месяцОбзор курса

Больше программ — в полном каталоге курсов по C (язык Си)

План входа в профессию по месяцам есть в статье как стать программистом на Си с нуля, а где такие специалисты работают, рассказывает разбор кто такой разработчик на Си.

Часто задаваемые вопросы

Что означает знак % в языке C?

Это остаток от деления целых чисел: 17 % 5 равно 2. Знак остатка совпадает со знаком делимого, поэтому -7 % 2 даёт −1. С дробными числами оператор не работает, для них есть функция fmod() из math.h.

Почему 5 / 2 в C равно 2?

Если оба операнда целые, C делит нацело и отбрасывает дробную часть. Чтобы получить 2.5, сделайте хотя бы один операнд вещественным: 5 / 2.0 или (double)a / b.

Чем i++ отличается от ++i?

Постфиксный i++ возвращает старое значение и потом увеличивает переменную, префиксный ++i сначала увеличивает и возвращает новое. Отдельной строкой разницы нет, она видна только внутри выражения, например a = i++.

Чем & отличается от && в C?

& сравнивает числа побитово, && проверяет, что оба операнда ненулевые, и не вычисляет правую часть, если левая равна нулю. 2 & 1 даёт 0, а 2 && 1 даёт 1.

Какие операторы в C выполняются первыми?

Сильнее всех связывают постфиксные ++, --, вызов функции и индекс массива, за ними унарные операторы, потом *, /, % и только затем + и -. Побитовые &, ^, | слабее сравнения, поэтому в выражениях с ними ставьте скобки. Последние в списке присваивание и запятая.

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!