значения изменились в битовых полях в структуре

Кто-нибудь может объяснить вывод, как значение хранится и рассчитывается?

#include<stdio.h>
struct bitfield
{
unsigned f1:1;
unsigned f2:2;
unsigned   :3;
unsigned f4:4;
unsigned f5:5;
unsigned f6:6;
unsigned f7:1;
unsigned f8:8;
} bf;

main()
{
bf.f1 = 1;
bf.f2 = 0x3;
bf.f4 = 0xff;
bf.f5 = -4;
bf.f6 = 0377;
printf("%d %d %d %d %d %d", bf.f1, bf.f2, bf.f4, bf.f5, bf.f6, bf.f8);
}

Выход: 1 3 15 28 63 0

-2

Решение

unsigned fx:n; // Only use the least significant n bits.

//                        Binary    Decimal
bf.f1 = 1;     // 1    == [0000 0001]:1   == 1      == 1
bf.f2 = 0x3;   // 0x3  == [0000 0011]:2   == 11     == 3
bf.f4 = 0xff;  // 0xff == [1111 1111]:4   == 1111   == 15
bf.f5 = -4;    // -4   == [0xfffffffc]:5  == 11100  == 28
bf.f6 = 0377;  // 0377 == [1111 1111]:6   == 111111 == 63
1

Другие решения

Очень короткое краткое изложение.

Первый, bf неинициализированная глобальная переменная Это означает, что это закончится в .bss сегмент, который обычно инициализируется нулем при запуске (хотя вы можете передать -fno-zero-initialized-in-bss GCC, чтобы остановить это, не уверен насчет MSVC, и, конечно, это зависит от вашего crt0). Это объясняет ценность f8, так как ты не написал ему.

f1 1. Вы назначаете 1. Это очевидно. То же самое с f2 (поскольку гекс 3 — это декабрь 3).

f4 потому что поле для f4 имеет ширину всего 4 бита. 0xFF представляет собой 8-битный шаблон, который представляет собой все единицы, который затем усекается до 4 битов и, следовательно, равен 15 (самое высокое значение, которое может быть представлено 4 битами).

f5 происходит из-за подписанного / неподписанного преобразования. Комплемент 5-битного двоичного представления -4 равен 11100. Если вы интерпретируете это значение как беззнаковое (или, скорее, просто двоичное число -> десятичное преобразование), вы получите 28.

f6 63 из-за восьмеричного преобразования. Любое литеральное число C, начинающееся с нуля, рассматривается как восьмеричное. Восьмеричное число 377 является десятичным 255 (то есть 11111111 в 8 битах), которое затем усекается до 6 бит, оставляя 111111, Это 63.

4

Значения хранятся в указанном вами поле. Однако, поскольку в некоторых случаях, например, bf.f4 = 0xff;, значение не подходит, оно будет терять старшие биты, следовательно, оно печатает 15 (0x0F). Аналогично для -4 хранится в f5 -4 = 0xFFFFFFFC как 32-разрядное целое число, но при сохранении в виде 5-разрядного целого без знака оно становится 0x1C или 28. Тот же принцип применяется к f6,

Существует также 3-разрядный «пробел» с использованием неназванного члена между f2 а также f4,

Внутри компилятор сделает это с помощью операций AND, SHIFT и OR.

Обратите внимание, что мы не можем знать, если f1 это самый высокий или самый низкий бит всего значения, в котором хранятся поля. Это будет зависеть от реализации компилятора — при условии, что это делается одинаково каждый раз.

2

unsigned f1:1;           // 1 bit is allocated.
bf.f1=1;                 // you are storing 1 works fine.

unsigned f2:2;           // 2 bit is allocated.
bf.f2=0x3;               // 3 == '11' in binary so 2 bits are enough so when you print 3 is printed.

unsigned   :3;

unsigned f4:4;          // 4 bit is allocated.
bf.f4=0xff;             // ff is represented as 1111 1111 in binary,
// but only 4 bits are allocated so only f which is 1111
// in binary gets stored in this. when you print using %d, 15 is getting printed.unsigned f5:5;         // 5 bits are allocated
bf.f5=-4;              // -4 in binary for 5 bits is 11100 but you are printing it as %d so it will print 28. and so on...

надеюсь, это поможет.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector