#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;
}
Просто убедитесь, что не превысите емкость самого битового поля и не полагайтесь на порядок расположения полей в одном машинном слове
Комментарии:
1. @Marco_A. спасибо за ответ, вы подходите для этого. Как насчет, например, id.required (я спросил это, потому что это всего лишь один бит.) Могу ли я инициализировать ее с помощью obj.id.required =1?
2. @Marco_A. вы подчеркиваете, что использование memset — неправильная идея? (жирной линией ?)
3. @newbornToCS нет, но если вам нужно задавать поля напрямую, без байтовой адресации, этот способ проще и практичнее. Я отредактировал вопрос с примером для required, хотя.