Страница 1 из 1

Битовое поле в структуре

Добавлено: 26 мар 2016, 18:28
Kazanove
как в битовое поле в структуре ввести данные через клавиатуру (cin - не приемлемо)

Re: битовое поле в структуре

Добавлено: 26 мар 2016, 21:38
Romeo
Прочитать в переменную с помощью scanf (раз cin не приемлем), а затем наложить помощью сдвига и побитового and наложить прочитанные биты в нужную часть поля. Пример смогу дать после того, как дашь более точные требования (объявление структуры, тип поля и требуемые битовые смещения).

Re: битовое поле в структуре

Добавлено: 27 мар 2016, 21:53
Kazanove
через scanf какой спецификатор использовать

Re: Битовое поле в структуре

Добавлено: 27 мар 2016, 22:39
Romeo
Читать нужно целое, так что подойдёт %d. Самое интересное начинается как раз после чтения. Прочитанное целое нужно маской впихнуть в нужные биты.

Re: Битовое поле в структуре

Добавлено: 30 мар 2016, 09:14
Kazanove
вот ту как раз и начинается самое интересное какой маской, "%d" не работает, в спецификации данной функции ни чего ненашел

Re: Битовое поле в структуре

Добавлено: 30 мар 2016, 11:51
Romeo
Пример структуры с битовыми полями взят из статьи на MSDN об эти самых полях.

Предположим у нас есть вот такая структура:

Код: Выделить всё

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)
};
Вопрос: как записать nMonthDay?

Во-первых, поле начинается с бита номер 3, так как первые три бита (с индексами 0-2), занимает nWeekDay. Это, как минимум, полезно знать.

Во-вторых, поле имеет длину 6 бит, и нам обязательно нужно обеспечить проверку длины данных, которые ввёл пользователь, и обрезание лишних бит, иначе при записи nMonthDay мы можем повредить следующие за ним в памяти поле nMonth.

Исходя из всего вышеуказанного, код будет выглядеть примерно так:

Код: Выделить всё

int nMonthDay = 0;
scanf("%d", &nMonthDay);
nMonthDay &= 63; // Очищаем все биты, кроме младших 6-ти

struct Date date;
date.nMonthDay = nMonthDay;
Подчёркиваю, что попытка считать данные сразу в date.nMonthDay обречена на провал. Причина проста: у выражения date.nMonthDay нельзя взять адрес, так как физически это поле начинается не с начала байта, а адресовать можно только целые байты.

P.S. Если что, число 63 взято не с потолка. Это (2 в степени 6) минус 1. В бинарном виде такое число выглядит, как шесть единиц (111111). Наложив такую маску на число, мы сохраняем эти (то бишь младшие) шесть бит, как есть. Остальные же биты будут очищены.

Re: Битовое поле в структуре

Добавлено: 30 мар 2016, 21:48
Kazanove
Что то вроде этого если я правильно все понял?

Код: Выделить всё

#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);
}
установки и получения времени в(из) битовое(-го) поле(-я).

Re: Битовое поле в структуре

Добавлено: 30 мар 2016, 22:23
Romeo
У тебя сделаны циклы для каждого поля, которые не позволят ввести неправильное значение, так что в таком случае наложение масок и не нужно. В остальном всё очень похоже на правду.

Re: Битовое поле в структуре

Добавлено: 31 мар 2016, 15:47
Kazanove
спасибо .