Muadib 0 7 апреля, 2012 Опубликовано 7 апреля, 2012 · Жалоба как объявить битовый массив к примеру а[j] of byte и как с ним работать, помогите. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 апреля, 2012 Опубликовано 7 апреля, 2012 · Жалоба Использовать битовые поля в структуре Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muadib 0 7 апреля, 2012 Опубликовано 7 апреля, 2012 · Жалоба да но потом как обращатся к нему в цикле struct { unsigned j1: 1; ............ unsigned j90: 1; } status[60]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muadib 0 7 апреля, 2012 Опубликовано 7 апреля, 2012 (изменено) · Жалоба для ясности вот к примеру этот код, а как он будет выглядеть на си. 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; Изменено 7 апреля, 2012 пользователем Muadib Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 7 апреля, 2012 Опубликовано 7 апреля, 2012 · Жалоба для ясности вот к примеру этот код, а как он будет выглядеть на си. 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; На Си никак - типа bit не существует. Можно пробовать на С++ что-нибудь: создать свой класс, перегрузить операторы и тд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demitar 0 7 апреля, 2012 Опубликовано 7 апреля, 2012 (изменено) · Жалоба в с++ для этих целей есть std::vector<bool>, но, поскольку, он тяжелый, можно как-то так извратиться: #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; } Изменено 6 мая, 2012 пользователем IgorKossak длинные строки вызывают горизонтальный скроллинг Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 7 апреля, 2012 Опубликовано 7 апреля, 2012 · Жалоба Можно сделать функции для записи и чтения бита. Вот пример для одномерного массива: #define NUMBITS 123 uint8_t bits[(NUMBITS + 7) / 8]; int getbit(uint8_t *src, int n) { return !!(src[n / 8] & (1 << (n % 8))); } void putbit(uint8_t *dst, int n, int val) { dst += n / 8; if (val == 0) { *dst &= ~(1 << (n % 8)); } else { *dst |= (1 << (n % 8)); } } int main(void) { putbit(bits, 34, 1); printf("%d", getbit(bits, 34)); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muadib 0 8 апреля, 2012 Опубликовано 8 апреля, 2012 (изменено) · Жалоба вот мне вариант scifi: больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar или я не прав? а для представления двумерного масива можно и одномерным обойтись. Изменено 8 апреля, 2012 пользователем Muadib Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 8 апреля, 2012 Опубликовано 8 апреля, 2012 · Жалоба вот мне вариант scifi: больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar А может больше нравится потому что понятней что написано? Зато у demitar-а универсальней. Насчёт скорости - вопрос. Как бы не одинаковая скорость, при прочих равных. памяти меньше занимает И насколько меньше? Цифры есть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demitar 0 8 апреля, 2012 Опубликовано 8 апреля, 2012 · Жалоба вот мне вариант scifi больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar или я не прав? а для представления двумерного масива можно и одномерным обойтись. да, будет чуть быстрее и меньше - за счет отсутствия сохранения промежуточных результатов в памяти. Точный ответ по скорости может дать только компилятор. Как всегда, только Вам решать, что для Вас важнее - наглядность или экономия нескольких тактов/байт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Muadib 0 8 апреля, 2012 Опубликовано 8 апреля, 2012 · Жалоба Да конечно вариант scifi легче для понимания, цифр нет, но пробую оба варианта прокрутить а там видно будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 8 апреля, 2012 Опубликовано 8 апреля, 2012 · Жалоба Мой вариант хорош тем, что не требуется знания Си++. Кто бы что ни говорил, но язык Си значительно проще, и это его огромный плюс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pasha 111 0 6 мая, 2012 Опубликовано 6 мая, 2012 (изменено) · Жалоба Делал в своё время класс для работы с монохромным изображением. Тут, как я понял, нужно тоже самое. Bitmap_mono.h #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.cpp //------------------------------------------------------------------------------ #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'е и сколько памяти будет занимать. Изменено 6 мая, 2012 пользователем IgorKossak [codebox] для длинного кода Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться