инициализация битов структуры, которая содержит другие структуры C

#c #struct #bit-manipulation

#c #struct #манипулирование битами

Вопрос:

У меня есть переменная struct, подобная приведенной ниже.(Я изменил имена переменных, поэтому они не имеют смысла.) У меня проблема с инициализацией битов массива myStruct1.

Мне нужно инициализировать, myStruct1.id.lengthOfData например, 40 и numberOfBits.number = 16. Для этого я пытался использовать memset и т.д., Но я не смог сделать это правильно. Как я мог бы это сделать, а не делать это вручную? Заранее спасибо.

 #define unsigned int INT32U
typedef struct{
    struct{
        INT32U lengthOfData  :16;                       
        INT32U command   :8;                                                            
        INT32U sendBack  :1;                                
        INT32U backTest  :1;                                        
        INT32U required :1;                 
        INT32U reserved  :5;                                        
        INT32U student_class_id ;                      
    }id;
    union{
        INT32U number;
        struct{
            INT32U firstFiveBits:5;                          
            INT32U secondFiveBits:5;                        
            INT32U thirdFiveBits :5;                                                                                                                                                    INT32U eightBits :8;                        
            INT32U secondEightBits :8;                              
            INT32U restOfit:1;                          
        }numberOfbits;
    }foo;
    union{
        INT32U numberTwo;
        struct{
            INT16U firstSteenBits:16;
            INT16U secondSteenBits  :16;
        }bits;      
    }myUnion;
}myStruct1;
  

Редактировать

Вот что я сделал до сих пор.

 myStruct1 *myPtr;
    myPtr = new myStruct1;


    memset((myPtr), 0, sizeof(*myPtr)); // to zeros for all bits of myStruct1
    memset((myPtr), 3,1); // to give 3 to lengthOfData.
  

Комментарии:

1. Можете ли вы опубликовать то, что вы пробовали? Также: возможно, вы захотите попробовать с побитовыми операциями, а также с самой простой вещью, которую можно попробовать

2. @MarcoA. Я добавил это в свой вопрос

3. @MarcoA. Я также отредактировал ее с помощью моей последней версии кода

Ответ №1:

Поскольку вы имеете дело с битовыми полями, вы можете просто использовать и инициализировать их как обычное поле struct

 #include <iostream>
using namespace std;

#define INT32U unsigned int
#define INT16U unsigned short

typedef struct{
    struct{
        INT32U lengthOfData  :16;                       
        INT32U command   :8;                                                            
        INT32U sendBack  :1;                                
        INT32U backTest  :1;                                        
        INT32U required :1;                 
        INT32U reserved  :5;                                        
        INT32U student_class_id ;                      
    }id;
    union{
        INT32U number;
        struct{
            INT32U firstFiveBits:5;                          
            INT32U secondFiveBits:5;                        
            INT32U thirdFiveBits :5;                                                                                                                                                    INT32U eightBits :8;                        
            INT32U secondEightBits :8;                              
            INT32U restOfit:1;                          
        }numberOfbits;
    }foo;
    union{
        INT32U numberTwo;
        struct{
            INT16U firstSteenBits:16;
            INT16U secondSteenBits  :16;
        }bits;      
    }myUnion;
}myStruct1;

int main() {
    myStruct1 obj;
    obj.id.required = 1; // Make sure not to exceed the bit capacity
    obj.id.lengthOfData = 22; // Make sure not to exceed the bit capacity
    cout << obj.id.lengthOfData << endl;
    cout << obj.id.required << endl;
    obj.id.required = 0;
    cout << obj.id.required << endl;

    return 0;
}
  

http://ideone.com/PUSp1h

Просто убедитесь, что не превысите емкость самого битового поля и не полагайтесь на порядок расположения полей в одном машинном слове

Комментарии:

1. @Marco_A. спасибо за ответ, вы подходите для этого. Как насчет, например, id.required (я спросил это, потому что это всего лишь один бит.) Могу ли я инициализировать ее с помощью obj.id.required =1?

2. @Marco_A. вы подчеркиваете, что использование memset — неправильная идея? (жирной линией ?)

3. @newbornToCS нет, но если вам нужно задавать поля напрямую, без байтовой адресации, этот способ проще и практичнее. Я отредактировал вопрос с примером для required, хотя.