Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Битовые поля передача по аргументу, Изменить битовое поле в функции 
V
    Опции темы
null56
Дата 6.5.2009, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



Я не совсем представляю, что из себя предсталяют битовые поля после компиляции и на сколько быстро идет к ним обращение по сравнению с отедельно взятой переменной, но я их использую, как флаги
Код

struct TBitMap
{
    unsigned char m_Bit : 1;
   // и т.д.
};

Собственно хотел спросить, возможен ли такой вариант
есть функция, которая принимает битовое поле и имеет возможность изменить его внутри тела?
надеюсь вопрос понятен... приведу пример кода, который может сделает вопрос более конкретным
Код

TBitMap MyBitMap;

void changeBitField(unsigned char & /** собственно битовое поле*/)
{
     /* битовое поле*/ = 1;
}

// вызов
changeBitField(MyBitMap.m_Bit);

Если не сложно, дополните вопрос с пояснением.... потому что для меня битовые поля - это максимально упакованные значения, как с ними работает компилятор, я уже говорил, не представляю...
Заранее благодарен за помощь
PM MAIL   Вверх
zim22
Дата 6.5.2009, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(null56 @  6.5.2009,  11:29 Найти цитируемый пост)
unsigned char m_Bit : 1;

я думал, должен быть тип unsigned int

Код

typedef unsigned int Bit;
class File {
public:
  void write() {
    modified = 1;
  }
private:
  Bit mode: 2;
  Bit modified: 1;
  Bit prot_owner: 3;
  Bit prot_group: 3;
  Bit prot_world: 3;
};

Для манипулирования битовыми полями с несколькими битами обычно используют встроенные побитовые операторы
Код

enum {READ = 01, WRITE = 02}; // режимы файла
int main() {
  File myFile;
  myFile.mode |= READ; // установить бит READ
  if (myFile.mode & READ); // если бит READ установлен
}


Классы, в которых определены битовые поля обычно снабжены и встраиваемыми методами, облегчающие установку и проверку значений битовых полей.
Например класс File мог содержать такие функции:
Код

inline int File::isRead() { return mode & READ; }
inline int File::isWrite() { return mode & WRITE; }

if (myFile.isRead());


Это сообщение отредактировал(а) zim22 - 6.5.2009, 11:58


--------------------
PM MAIL   Вверх
math64
Дата 6.5.2009, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Получить ссылку на битовое нельзя. Можно разве что так:
Код

struct TBitmap {
   unsigned char bit1 : 1;
   unsigned char bit2 : 1;
   unsigned char bit3 : 1;
   unsigned char bit4 : 1;
   void SetBit(int bit, int value);
   int GetBit(int bit);
};
void TBitmap::SetBit(int bit, int value) {
   switch(bit) {
      case 1:  bit1 = value; break;
      case 2:  bit2 = value; break;
      case 3:  bit3 = value; break;
      case 4:  bit4 = value; break;
   }
}

int TBitmap::GetBit(int bit) {
   switch(bit) {
      case 1:  return bit1;
      case 2:  return bit2;
      case 3:  return bit3;
      case 4:  return bit4;
   }
}


PM   Вверх
xvr
Дата 6.5.2009, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(null56 @ 6.5.2009,  11:29)
Я не совсем представляю, что из себя предсталяют битовые поля после компиляции и на сколько быстро идет к ним обращение по сравнению с отедельно взятой переменной,

Медленнее
Цитата

Собственно хотел спросить, возможен ли такой вариант
есть функция, которая принимает битовое поле
Невозможен. Битовое поле не существует вне струкутры, где описанно. И указатель на него взять нельзя (а значит и передать по референсу)

Цитата

Если не сложно, дополните вопрос с пояснением.... потому что для меня битовые поля - это максимально упакованные значения, как с ними работает компилятор, я уже говорил, не представляю...
Ну как то так:
Код

struct BitTest {
 int bf1: 1;
 int bf2: 1;
} tst;
/* Real structure will be
struct BitTest {
 int all_bf;
} rtst;
*/
tst.bf1=1; // real op: rtst.all_bf|=1;
tst.bf1=0; // real op: rtst.all_bf&=~1;
tst.bf2=1; // real op: rtst.all_bf|=2;
tst.bf2=0; // real op: rtst.all_bf&=~2;
if (tst.bf2) // real op: if (rtst.all_bf&2)


PM MAIL   Вверх
math64
Дата 6.5.2009, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Вместо битовых полей можно использовать маски:
Код

enum Bit { bit1, bit2, bit3, bit4 };
inline bool TestBit(int&mask, Bit bit) { return mask & (1 << bit) ? true : false; }
inline SetBit(int&mask, Bit bit) { mask |= (1 << bit); }
inline ClrBit(int&mask, Bit bit) { mask &= ~(1 << bit); }
inline XorBit(int&mask, Bit bit) { mask ^= (1 << bit); }
inline SetBit(int&mask, Bit bit, bool value) { if (value) SetBit(mask, bit); else ClrBit(mask, bit); }

Код сгенерированный компилятором будет примерно одинаковым, что и применении битовых полей.
PM   Вверх
null56
Дата 6.5.2009, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



Значит попробую сделать выводы.
В С++ битовое поле призвано повысить уровень абстракции, чтобы пользователю самому не приходилось реализовывать битовые операции, но компилятор в исходном машинном коде все равно будет делать тоже самое, что и делал бы пользователь, а именно те же сбросы или выставлаения битов
Сама структура с битовыми полями является байтом или более широким словом и по сути к ней можно обращаться и передавать как одну переменную и работать с ней используя битовые операции для изменения значений отдельных битов, это будет аналогично использованию возможностей компилятора по обращению к отдельным битовым полям...

Если я все верно понял, то отлично...
Все спасибо за подробные ответы
PM MAIL   Вверх
zim22
Дата 6.5.2009, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(null56 @  6.5.2009,  12:18 Найти цитируемый пост)
В С++ битовое поле призвано повысить уровень абстракции, чтобы пользователю самому не приходилось реализовывать битовые операции

уровень абстракции повысит класс из #include <bitset>

Битовые поля обычно используют в случае, когда программа должна передать бинарные данные другой программе или аппаратному устройству.
Расположение в памяти битовых полей является машинно-зависимым.

Это сообщение отредактировал(а) zim22 - 6.5.2009, 12:32


--------------------
PM MAIL   Вверх
null56
Дата 6.5.2009, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



Цитата(zim22 @ 6.5.2009,  12:28)
Битовые поля обычно используют в случае, когда программа должна передать бинарные данные другой программе или аппаратному устройству.
Расположение в памяти битовых полей является машинно-зависимым.

вот это верно подмечено.... по моему, проще потратить 9 байт на флаги, чем связываться с битовыми полями в моем случае... было бы их штук 30, тогда другой вопрос... хотя даже не знаю....
Вопрос такой, если мы объявляем структуру битового поля, то уже не имеем возможности обращаться к полям через собсвтенные битовые операции, только средствами компилятора?
подробнее на коде... так делать никак нельзя?
Код

struct BitField
{
   unsigned char bit_1 : 1;
   unsigned char bit_2 : 1;
};

BitField bf;
bd |= 1; // НИЗЯ НИКАК? чтобы выставить первый бит

PM MAIL   Вверх
zim22
Дата 6.5.2009, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Код

bf.bit_1 |= 1; // ВОТ ТАК МОЖНО! чтобы выставить первый бит

и так можно:
Код

BitField bf2 = {1, 1}; // bit_1 = 1, bit2 = 1;


Это сообщение отредактировал(а) zim22 - 6.5.2009, 12:55


--------------------
PM MAIL   Вверх
math64
Дата 6.5.2009, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Код

struct BitField {
   union {
     struct {
       unsigned char bit_1 : 1;
       unsigned char bit_2 : 1;
     } bits;
     unsigned char mask;
   } u;
};

BitField bf;
bf.u.mask = 1;
bf.u.bits.bit_2 = bf.u.bits.bit_1;


PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1496 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.