Битовое поле в структуре
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
как в битовое поле в структуре ввести данные через клавиатуру (cin - не приемлемо)
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Прочитать в переменную с помощью scanf (раз cin не приемлем), а затем наложить помощью сдвига и побитового and наложить прочитанные биты в нужную часть поля. Пример смогу дать после того, как дашь более точные требования (объявление структуры, тип поля и требуемые битовые смещения).
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
через scanf какой спецификатор использовать
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Читать нужно целое, так что подойдёт %d. Самое интересное начинается как раз после чтения. Прочитанное целое нужно маской впихнуть в нужные биты.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
вот ту как раз и начинается самое интересное какой маской, "%d" не работает, в спецификации данной функции ни чего ненашел
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Пример структуры с битовыми полями взят из статьи на MSDN об эти самых полях.
Предположим у нас есть вот такая структура:
Вопрос: как записать nMonthDay?
Во-первых, поле начинается с бита номер 3, так как первые три бита (с индексами 0-2), занимает nWeekDay. Это, как минимум, полезно знать.
Во-вторых, поле имеет длину 6 бит, и нам обязательно нужно обеспечить проверку длины данных, которые ввёл пользователь, и обрезание лишних бит, иначе при записи nMonthDay мы можем повредить следующие за ним в памяти поле nMonth.
Исходя из всего вышеуказанного, код будет выглядеть примерно так:
Подчёркиваю, что попытка считать данные сразу в date.nMonthDay обречена на провал. Причина проста: у выражения date.nMonthDay нельзя взять адрес, так как физически это поле начинается не с начала байта, а адресовать можно только целые байты.
P.S. Если что, число 63 взято не с потолка. Это (2 в степени 6) минус 1. В бинарном виде такое число выглядит, как шесть единиц (111111). Наложив такую маску на число, мы сохраняем эти (то бишь младшие) шесть бит, как есть. Остальные же биты будут очищены.
Предположим у нас есть вот такая структура:
Код: Выделить всё
struct Date {
unsigned short nWeekDay : 3; // 0..7 (3 bits)
unsigned short nMonthDay : 6; // 0..31 (6 bits)
unsigned short nMonth : 5; // 0..12 (5 bits)
unsigned short nYear : 8; // 0..100 (8 bits)
};
Во-первых, поле начинается с бита номер 3, так как первые три бита (с индексами 0-2), занимает nWeekDay. Это, как минимум, полезно знать.
Во-вторых, поле имеет длину 6 бит, и нам обязательно нужно обеспечить проверку длины данных, которые ввёл пользователь, и обрезание лишних бит, иначе при записи nMonthDay мы можем повредить следующие за ним в памяти поле nMonth.
Исходя из всего вышеуказанного, код будет выглядеть примерно так:
Код: Выделить всё
int nMonthDay = 0;
scanf("%d", &nMonthDay);
nMonthDay &= 63; // Очищаем все биты, кроме младших 6-ти
struct Date date;
date.nMonthDay = nMonthDay;
P.S. Если что, число 63 взято не с потолка. Это (2 в степени 6) минус 1. В бинарном виде такое число выглядит, как шесть единиц (111111). Наложив такую маску на число, мы сохраняем эти (то бишь младшие) шесть бит, как есть. Остальные же биты будут очищены.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Что то вроде этого если я правильно все понял?
установки и получения времени в(из) битовое(-го) поле(-я).
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
struct BitClock{
unsigned short Hour : 5;
unsigned short Minute : 6;
unsigned short Second : 6;
unsigned short Millisecond : 10;
};
void main(void){
BitClock Clock;
int Hour = 0;
int Minute = 0;
int Second = 0;
int Milisecond = 0;
printf("Please enter time:\n");
do{
printf("Hour: ");
scanf("%d", &Hour);
} while (Hour < 0 || Hour > 23);
do{
printf("Minute: ");
scanf("%d", &Minute);
} while (Minute<0 || Minute > 59);
do{
printf("Second: ");
scanf("%d", &Second);
} while (Second<0 || Second>59);
do{
printf("Milisecond: ");
scanf("%d", &Milisecond);
} while (Milisecond<0 || Milisecond > 999);
Hour &= 31;
Minute &= 63;
Second &= 63;
Milisecond &= 1023;
Clock.Hour = Hour;
Clock.Minute = Minute;
Clock.Second = Second;
Clock.Millisecond = Milisecond;
printf("Нou enter the time %d:%d:%d.%d\n", Clock.Hour, Clock.Minute, Clock.Second, Clock.Millisecond);
}
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
У тебя сделаны циклы для каждого поля, которые не позволят ввести неправильное значение, так что в таком случае наложение масок и не нужно. В остальном всё очень похоже на правду.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.