Сдвиги
Сдвиг влево и вправо
«Сдвиги» — бесплатный урок C Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 4 уроков всего.
Сдвиг битов
Операторы сдвига перемещают все биты целого числа влево или вправо на заданное количество позиций.
Сдвиг влево обозначается как <<, а сдвиг вправо — как >>.
#include <stdio.h>
int main(void) {
unsigned x = 1;
printf("1 << 3 = %u\n", x << 3);
return 0;
}Сдвиг влево умножает
Сдвиг влево на n позиций умножает беззнаковое значение на 2 в степени n.
1 << 3 равно 8, а 5 << 1 равно 10.
#include <stdio.h>
int main(void) {
printf("5 << 1 = %u\n", 5u << 1);
printf("3 << 4 = %u\n", 3u << 4);
return 0;
}Сдвиг вправо делит
Сдвиг вправо на n позиций делит беззнаковое значение на 2 в степени n, отбрасывая биты, вышедшие за правый край.
20 >> 2 равно 5.
#include <stdio.h>
int main(void) {
printf("20 >> 2 = %u\n", 20u >> 2);
printf("7 >> 1 = %u\n", 7u >> 1);
return 0;
}Степени двойки
Сдвиг 1 влево — самый быстрый способ получить степени двойки.
1 << n — это n-я степень двойки.
#include <stdio.h>
int main(void) {
for (int n = 0; n < 6; n++) {
printf("2^%d = %u\n", n, 1u << n);
}
return 0;
}Визуализация сдвига
Вывод битов до и после операции показывает, как перемещается их последовательность.
#include <stdio.h>
void print_bits(unsigned char v) {
for (int i = 7; i >= 0; i--) putchar((v >> i) & 1 ? '1' : '0');
putchar('\n');
}
int main(void) {
unsigned char v = 0b00000110;
print_bits(v);
print_bits(v << 2);
return 0;
}Извлечение бита
Чтобы прочитать бит с номером i, сдвиньте значение вправо на i позиций и примените маску 1.
Результат равен 0 или 1.
#include <stdio.h>
int main(void) {
unsigned v = 0b10110;
for (int i = 0; i < 5; i++) {
printf("bit %d = %u\n", i, (v >> i) & 1);
}
return 0;
}Построение значения по битам
Можно собрать число, сдвигая биты на нужные позиции и объединяя их с помощью OR.
#include <stdio.h>
int main(void) {
unsigned v = 0;
v |= (1u << 0);
v |= (1u << 2);
v |= (1u << 4);
printf("v = %u\n", v);
return 0;
}Предупреждение о сдвиге отрицательных чисел вправо
Поведение при сдвиге отрицательного знакового целого числа вправо определяется реализацией: знаковый бит может копироваться.
Для предсказуемых побитовых операций предпочтительнее использовать типы unsigned.
#include <stdio.h>
int main(void) {
int s = -8;
printf("-8 >> 1 = %d (implementation-defined)\n", s >> 1);
unsigned u = 8;
printf("8u >> 1 = %u\n", u >> 1);
return 0;
}Избегайте чрезмерного сдвига
Сдвиг на величину, большую или равную разрядности типа, приводит к неопределённому поведению.
Сдвигать 32-битное значение на 32 разряда или больше нельзя.
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("unsigned has %zu bits\n", sizeof(unsigned) * CHAR_BIT);
printf("Safe shift 1u << 31 = %u\n", 1u << 31);
return 0;
}Сочетание сдвига и маски
С помощью сдвига и маски вместе можно извлечь поле из нескольких битов. Здесь мы извлекаем средние 4 бита из байта.
#include <stdio.h>
int main(void) {
unsigned v = 0b11010110;
unsigned field = (v >> 2) & 0b1111;
printf("field = %u\n", field);
return 0;
}Быстрое умножение и сложение
Сочетание сдвигов позволяет быстро умножать на константы. Умножение на 10 равносильно сдвигу на 3 разряда (умножению на 8) и сдвигу на 1 разряд (умножению на 2).
#include <stdio.h>
int main(void) {
unsigned x = 7;
unsigned times10 = (x << 3) + (x << 1);
printf("7 * 10 = %u\n", times10);
return 0;
}Быстрая проверка
Проверьте свои знания о сдвигах.
Повторение
Вы узнали об операторах сдвига:
<<сдвигает влево и умножает на степени двойки.>>сдвигает вправо и делит на степени двойки.(v >> i) & 1извлекает один бит.- Используйте
unsignedдля предсказуемых сдвигов и никогда не сдвигайте на количество разрядов типа или больше.
Часто задаваемые вопросы
Урок «Сдвиги» бесплатный?
Да — полный текст урока «Сдвиги» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 4 уроков всего.
Чему я научусь в уроке «Сдвиги»?
Сдвиг влево и вправо Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C Academy?
Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Сдвиги»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C Academy?
Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.