|
Битовый массив, как объявить |
|
|
|
Apr 7 2012, 12:57
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 10-12-07
Пользователь №: 33 170

|
как объявить битовый массив к примеру а[i][j] of byte и как с ним работать, помогите.
|
|
|
|
|
 |
Ответов
(1 - 12)
|
Apr 7 2012, 13:23
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 10-12-07
Пользователь №: 33 170

|
да но потом как обращатся к нему в цикле struct { unsigned j1: 1; ............ unsigned j90: 1;
} status[60];
|
|
|
|
|
Apr 7 2012, 14:55
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 10-12-07
Пользователь №: 33 170

|
для ясности вот к примеру этот код, а как он будет выглядеть на си.
A:array[0..N,0..M]of byte; // и в места byte чтоб бит был, так как это в 8 раз меньше места занимает
for i := 1 to N do begin for j := 1 to M do begin T[i,j]=1; end; end;
Сообщение отредактировал Muadib - Apr 7 2012, 15:01
|
|
|
|
|
Apr 7 2012, 18:12
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 3-09-09
Пользователь №: 52 170

|
в с++ для этих целей есть std::vector<bool>, но, поскольку, он тяжелый, можно как-то так извратиться: CODE #include <iostream> #include <cassert>
template <int SZ, typename BASE_T = unsigned int> // SZ - размер битового вектора, class bitvec { // BASE_Т - базовый тип, в зависимости от архитектуры МК BASE_T data[SZ / sizeof(BASE_T) + 1]; int shift; int idx;
public: bitvec<SZ>& operator[](int i) { // при вызове оператора [] просто считаем индекс элемента в массиве и сдвиг assert(i >= 0); assert(i < SZ); idx = i / sizeof(BASE_T); shift = i & (sizeof(BASE_T) - 1); return *this; // возвращаем ссылку на себя, чтобы работало присваивание и преобразование типов }
int operator=(int val) { // записываем значение бита, индекс и сдвиг расчитали раньше с помощью [] val = val != 0; data[idx] &= ~(1 << shift); data[idx] |= (val << shift); return val; }
operator int() { // приведение типа bitvec<> к int, чтобы работало присваивание a[i] = x, можно приводить к bool return (data[idx] & (1 << shift)) >> shift; } };
// bitvec<15> test; // объявляем вектор из 15 бит
int main() { bitvec<10> bits[20]; // объявляем массив 20x10
for(int i = 0; i < 20; ++i) { for(int j = 0; j < 10; ++j) { bits[i][j] = (i * j) & 1; // пишем std::cout << "bits[" << i << ", " << j << "] = "; std::cout << bits[i][j] << " (" << ((i * j) & 1) << ") "; // читаем, что записали std::cout << std::endl; } }
return 0; }
Сообщение отредактировал IgorKossak - May 6 2012, 19:00
Причина редактирования: длинные строки вызывают горизонтальный скроллинг
|
|
|
|
|
Apr 8 2012, 13:40
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 10-12-07
Пользователь №: 33 170

|
вот мне вариант scifi: больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar или я не прав? а для представления двумерного масива можно и одномерным обойтись.
Сообщение отредактировал Muadib - Apr 8 2012, 13:46
|
|
|
|
|
Apr 8 2012, 13:58
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Muadib @ Apr 8 2012, 16:40)  вот мне вариант scifi: больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar А может больше нравится потому что понятней что написано? Зато у demitar-а универсальней. Насчёт скорости - вопрос. Как бы не одинаковая скорость, при прочих равных. Цитата(Muadib @ Apr 8 2012, 16:40)  памяти меньше занимает И насколько меньше? Цифры есть?
|
|
|
|
|
Apr 8 2012, 16:52
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 3-09-09
Пользователь №: 52 170

|
Цитата(Muadib @ Apr 8 2012, 17:40)  вот мне вариант scifi больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar или я не прав? а для представления двумерного масива можно и одномерным обойтись. да, будет чуть быстрее и меньше - за счет отсутствия сохранения промежуточных результатов в памяти. Точный ответ по скорости может дать только компилятор. Как всегда, только Вам решать, что для Вас важнее - наглядность или экономия нескольких тактов/байт.
|
|
|
|
|
Apr 8 2012, 16:57
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 10-12-07
Пользователь №: 33 170

|
Да конечно вариант scifi легче для понимания, цифр нет, но пробую оба варианта прокрутить а там видно будет.
|
|
|
|
|
May 6 2012, 16:08
|

Частый гость
 
Группа: Свой
Сообщений: 154
Регистрация: 6-11-05
Из: Москва
Пользователь №: 10 515

|
Делал в своё время класс для работы с монохромным изображением. Тут, как я понял, нужно тоже самое. Bitmap_mono.hCODE #ifndef _CCBITMAP_MONO_H #define _CCBITMAP_MONO_H
// Типы данных #ifndef TYPES_DEFINED #define TYPES_DEFINED typedef signed long long int64; typedef signed int int32; typedef signed short int int16; typedef signed char int8; typedef unsigned long long uint64; typedef unsigned int uint32; typedef unsigned short int uint16; typedef unsigned char uint8; #endif
class CBITMAP_MONO { private: uint8 *buf; uint32 width; uint32 height;
public: CBITMAP_MONO(void); ~CBITMAP_MONO(void);
uint32 bind(uint8 *new_buf, uint32 new_width, uint32 new_height);
void clear(uint32 color); void invert();
void set_pixel(uint32 x, uint32 y, uint32 color); uint32 get_pixel(uint32 x, uint32 y); }; #endif Bitmap_mono.cppCODE //------------------------------------------------------------------------------
#include "Bitmap_mono.h"
//------------------------------------------------------------------------------
CBITMAP_MONO::CBITMAP_MONO(void) { buf = 0; }
//------------------------------------------------------------------------------
CBITMAP_MONO::~CBITMAP_MONO(void) { }
//------------------------------------------------------------------------------
uint32 CBITMAP_MONO::bind(uint8 *new_buf, uint32 new_width, uint32 new_height) { if(new_buf == 0) return 0; if(new_width == 0) return 0; if(new_height == 0) return 0;
buf = new_buf; width = new_width; height = new_height;
return 1; }
//------------------------------------------------------------------------------
void CBITMAP_MONO::clear(uint32 color) { uint32 size = width * height / 8; if((width * height) % 8) size++; if(color) { for(uint32 i = 0; i < size; i++) buf[i] = 0xFF; } else { for(uint32 i = 0; i < size; i++) buf[i] = 0x00; } }
//------------------------------------------------------------------------------
void CBITMAP_MONO::invert() { uint32 size = width * height / 8; if((width * height) % 8) size++; for(uint32 i = 0; i < size; i++) buf[i] = ~buf[i]; }
//------------------------------------------------------------------------------
void CBITMAP_MONO::set_pixel(uint32 x, uint32 y, uint32 color) { if(x >= width) return; if(y >= height) return;
uint32 pix_num = y * width + x; uint32 byte_num = pix_num / 8; uint8 img_byte = buf[byte_num];
if(color) { img_byte |= 1 << (pix_num % 8); buf[byte_num] = img_byte; } else { img_byte &= ~(1 << (pix_num % 8)); buf[byte_num] = img_byte; } }
//------------------------------------------------------------------------------
uint32 CBITMAP_MONO::get_pixel(uint32 x, uint32 y) { if(x >= width) return 0x000000; if(y >= height) return 0x000000;
uint32 pix_num = y * width + x; uint32 byte_num = pix_num / 8; uint8 img_byte = buf[byte_num];
if(img_byte & (1 << (pix_num % 8))) return 0xFFFFFF; else return 0x000000; }
//------------------------------------------------------------------------------ Использование: Код const uint32 width = 20; const uint32 height = 35; uint8 buf[width * height / 8 + 1];
CBITMAP_MONO bmp; bmp.bind(buf, width, height);
bmp.set_pixel(3, 14, 1);
if(bmp.get_pixel(3, 14)) { // .... } Да, если хочется юзать STL, то там есть стандартный контейнер - bitset http://www.cplusplus.com/reference/stl/bitset/Правда неизвестно как он реализован в IAR'е и сколько памяти будет занимать.
Сообщение отредактировал IgorKossak - May 6 2012, 18:58
Причина редактирования: [codebox] для длинного кода
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|