Переопределите структуру с символом, почему получили следующий результат на процессоре Intel? - PullRequest
0 голосов
/ 02 ноября 2011

Я смущен следующим кодом:

#include <iostream> 

using namespace std;

struct bit 
{
    int a:3; 
    int b:2; 
    int c:3; 
}; 
int main(int argc, char* argv[]) 
{ 
    bit s; 
    char *c = (char*)&s; 
    *c = 0x99; 
    cout << s.a <<endl <<s.b<<endl<<s.c<<endl; 
    return 0; 
}

Поскольку a занимает 3 бита, b 2 бита, c 3 бита, когда я приводил эту структуру к указателю char *, я взял first 8 байт или last 8 байт?

  1. На 32-разрядной машине Intel, как компилятор будет хранить 32-разрядное целое число?

  2. Почему я получаю 1 , -1 , -4 в результате?

Ответы [ 4 ]

4 голосов
/ 02 ноября 2011

0x99 - 10011001, двоичное - 100 11 001, что очень похоже на 1, -1, -4 (в обратном порядке). И да, это 8 младших разрядов.

Я думаю, что подписанность смутила вас, поэтому вы можете использовать unsigned int в структуре. Если это не подпись, то, пожалуйста, будьте более конкретны.

3 голосов
/ 02 ноября 2011

Здесь есть как минимум три проблемы.Первое (уже упомянутое) - это порядок байтов.Вторым является то, что размер bit заканчивается.(Это будет четыре байта на многих компиляторах.) Если это больше, чем один байт, то ваш char* не сможет получить доступ ко всем этим.И, наконец, возникает вопрос о том, как компилятор размещает биты и куда он помещает оставшиеся биты.Некоторые компиляторы начнут с их размещения из старшего бита, а другие - из младшего бита.Если компилятор использует только один 8-битовый char для bit, то в зависимости от порядка вы можете получить {[+ -] 4, 3 или -1, 1} или наоборот.Не говоря уже о том, что при использовании в качестве битового поля обычный int может быть либо signed int, либо unsigned int (таким образом, [+ -] 4 и 3 или -1).(Во всех других контекстах обычный int равен signed int, и с точки зрения QoI это то, что я ожидал бы здесь, хотя бы по соображениям согласованности.)

В общем, если выЕдинственная цель состоит в том, чтобы сохранить память в структуре в памяти, битовые поля в порядке.Но они бесполезны, как только вы пытаетесь сопоставить какое-то внешнее представление.

0 голосов
/ 03 ноября 2011

Ваша структура имеет размер более 1 байта из-за использования int, но вы пытаетесь присвоить 1-байтовое значение всему содержимому структуры.Это не будет работать.Измените вашу структуру, чтобы использовать char вместо int, тем более что вы используете указатель char* для присвоения значения.Общее количество битов, указанное членами структуры, должно соответствовать размеру байта используемого базового типа данных, например:

struct bit
{
    char a:3;
    char b:2;
    char c:3;
};  

В связанной ноте вы можете использовать union, чтобы избежать char* указатель:

union bit
{
    struct
    {
        char a:3;
        char b:2;
        char c:3;
    };
    char value;
};  

int main(int argc, char* argv[])
{
    bit s;
    s.value = 0x99;
    std::cout << (int)s.a << std::endl << (int)s.b << std::endl << (int)s.c << std::endl;
    return 0;
}     
0 голосов
/ 02 ноября 2011

Прежде всего, так как вы используете int, подписывая членов структуры

*ch = 0x00  -> s.a = 0 s.b = 0 s.c = 0
*ch = 0x01  -> s.a = 1 s.b = 0 s.c = 0
*ch = 0x04  -> s.a = -4 s.b = 0 s.c = 0
*ch = 0x05  -> s.a = -3 s.b = 0 s.c = 0

В зависимости от того, есть ли у вас машина Big или Little Endian.

...