Перейти к содержанию
    

Битовый массив

да но потом как обращатся к нему в цикле

struct {

unsigned j1: 1;

............

unsigned j90: 1;

 

} status[60];

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

для ясности вот к примеру этот код, а как он будет выглядеть на си.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

для ясности вот к примеру этот код, а как он будет выглядеть на си.

 

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 не существует.

Можно пробовать на С++ что-нибудь: создать свой класс, перегрузить операторы и тд.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в с++ для этих целей есть 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;
}

Изменено пользователем IgorKossak
длинные строки вызывают горизонтальный скроллинг

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно сделать функции для записи и чтения бита. Вот пример для одномерного массива:

#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));
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот мне вариант scifi: больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar

или я не прав? а для представления двумерного масива можно и одномерным обойтись.

Изменено пользователем Muadib

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот мне вариант scifi: больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar

А может больше нравится потому что понятней что написано?

Зато у demitar-а универсальней.

Насчёт скорости - вопрос. Как бы не одинаковая скорость, при прочих равных.

 

памяти меньше занимает

И насколько меньше? Цифры есть?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот мне вариант scifi больше нравится поскольку памяти меньше занимает и по скорости шустрее будет чем вариант demitar

или я не прав? а для представления двумерного масива можно и одномерным обойтись.

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

Как всегда, только Вам решать, что для Вас важнее - наглядность или экономия нескольких тактов/байт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да конечно вариант scifi легче для понимания, цифр нет, но пробую оба варианта прокрутить а там видно будет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делал в своё время класс для работы с монохромным изображением. Тут, как я понял, нужно тоже самое.

 

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'е и сколько памяти будет занимать.

Изменено пользователем IgorKossak
[codebox] для длинного кода

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...