Есть массив элементов типа unsigned long int DI[100]; есть указатель на начало массива unsigned char *ptr; можно ли сдвинуть указатель на несколько битов вперед относительно начала массива, так чтобы он указывал допустим на 3-й бит первого элемента массива? и как это реализовать? Заранее спасибо.
Здравствуйте, Аноним, Вы писали:
А>Есть массив элементов типа unsigned long int DI[100]; есть указатель на начало массива unsigned char *ptr; можно ли сдвинуть указатель на несколько битов вперед относительно начала массива, так чтобы он указывал допустим на 3-й бит первого элемента массива? и как это реализовать? Заранее спасибо.
Нет. Минимальная адресуемая сущность — это байт.
А зачем нужно?
Любите книгу — источник знаний (с) М.Горький
Re[2]: Как сдвинуть указатель на несколько бит?
От:
Аноним
Дата:
16.10.06 06:43
Оценка:
Мне надо найти в массиве DI запрашиваемый бит и шагать побайтно, потом с полученными данными дальше работать. Мне надо реализовать вторую функцию Modbus.
Re: Как сдвинуть указатель на несколько бит?
От:
Аноним
Дата:
16.10.06 06:48
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Есть массив элементов типа unsigned long int DI[100]; есть указатель на начало массива unsigned char *ptr; можно ли сдвинуть указатель на несколько битов вперед относительно начала массива, так чтобы он указывал допустим на 3-й бит первого элемента массива? и как это реализовать? Заранее спасибо.
Для этого достаточно обычных указателей и побитовых операций.
Указателей не "биты" не существует.
Здравствуйте, Аноним, Вы писали:
А>Мне надо найти в массиве DI запрашиваемый бит и шагать побайтно, потом с полученными данными дальше работать. Мне надо реализовать вторую функцию Modbus.
Найди этот бит, а потом передвинь все элементы так, чтобы получился нормальный массив, в котором и будет ptr++;
Re[4]: Как сдвинуть указатель на несколько бит?
От:
Аноним
Дата:
16.10.06 06:55
Оценка:
Как передвинуть, используя операции сдвига? можно подробней7
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Здравствуйте, <Аноним>, Вы писали:
А>Мне надо найти в массиве DI запрашиваемый бит и шагать побайтно, потом с полученными данными дальше работать. Мне надо реализовать вторую функцию Modbus.
Напиши адаптер. Степень адаптации может варьироваться — начиная от просто побайтового чтения
Здравствуйте, Аноним, Вы писали:
А>Есть массив элементов типа unsigned long int DI[100]; есть указатель на начало массива unsigned char *ptr; можно ли сдвинуть указатель на несколько битов вперед относительно начала массива, так чтобы он указывал допустим на 3-й бит первого элемента массива? и как это реализовать? Заранее спасибо.
А>>Есть массив элементов типа unsigned long int DI[100]; есть указатель на начало массива unsigned char *ptr; можно ли сдвинуть указатель на несколько битов вперед относительно начала массива, так чтобы он указывал допустим на 3-й бит первого элемента массива? и как это реализовать? Заранее спасибо.
А>Для этого достаточно обычных указателей и побитовых операций. А>Указателей не "биты" не существует.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Аноним, Вы писали:
А>>Есть массив элементов типа unsigned long int DI[100]; есть указатель на начало массива unsigned char *ptr; можно ли сдвинуть указатель на несколько битов вперед относительно начала массива, так чтобы он указывал допустим на 3-й бит первого элемента массива? и как это реализовать? Заранее спасибо.
Зачем интересно такое понадобилось? По-любому лаба.
R>
R>p = p + 0.25;
R>
R>
как не стыдно над новичками издеваться
собственно, чтобы сгладить первое впечатление набросок
#include <iostream>
#include <limits>
#include <iterator>
#include <bitset>
template< int shift = 0 >
struct shift_iterator
{
typedef std::random_access_iterator_tag iterator_category;
typedef unsigned long value_type;
struct reference;
typedef ptrdiff_t difference_type;
value_type * ptr;
shift_iterator ( value_type * src ) : ptr (src) {}
reference operator * () const { return reference (this->ptr); }
reference operator [] (difference_type) const;
template<typename T>
struct temporary {
T value;
explicit temporary ( T src ) : value (src) {}
T * operator -> () { return & this->value; }
};
temporary<reference> operator -> () const { return temporary<reference> ( reference (this->ptr) ); }
shift_iterator & operator ++ () { ++this->ptr; return (*this); }
shift_iterator & operator -- () { --this->ptr; return (*this); }
shift_iterator operator ++ (int) { shift_iterator tmp (*this); ++(*this); return tmp; }
shift_iterator operator -- (int) { shift_iterator tmp (*this); --(*this); return tmp; }
shift_iterator & operator += ( difference_type n ) { this->ptr += n; return (*this); }
shift_iterator & operator -= ( difference_type n ) { this->ptr -= n; return (*this); }
};
template< int shift >
struct shift_iterator<shift>::reference {
static const int digits = std::numeric_limits<value_type>::digits;
typedef std::bitset<digits> bitset;
value_type * ptr;
reference ( value_type * src ) : ptr (src) {}
value_type value () const {
std::cout << __FUNCTION__ << std::endl;
bitset tmp (*this->ptr); // берем текущий элемент.
std::cout << tmp.to_ulong () << ":" << tmp << std::endl;
bitset val = tmp >> shift; // удаляем хвост предынущего элемента. теперь val хранит младшую часть значения.
std::cout << val.to_ulong () << ":" << val << std::endl;
tmp = *(this->ptr+1); // берем следующий элемент.
std::cout << tmp.to_ulong () << ":" << tmp << std::endl;
tmp = (tmp << digits-shift); // получаем старшую чась значения.
std::cout << tmp.to_ulong () << ":" << tmp << std::endl;
val |= tmp; // склеиваем младшую и старшую части.
std::cout << val.to_ulong () << ":" << val << std::endl;
return val.to_ulong (); // возвращаем значение.
}
operator value_type () const { return this->value (); }
reference & operator = ( value_type value ) {
static bitset const mask = bitset ().set(); // все единицыstatic bitset const hmask= mask << shift; // старшая часть = единицыstatic bitset const lmask= ~ hmask; // младшая часть = единицы
std::cout << __FUNCTION__ << std::endl;
std::cout << lmask << std::endl;
std::cout << hmask << std::endl;
bitset tmp (*this->ptr); // берем текущий элемент.
bitset val (value); // и новое значение.
std::cout << tmp.to_ulong () << ":" << tmp << std::endl;
std::cout << val.to_ulong () << ":" << val << std::endl;
val = ( val << shift ) | ( val >> digits-shift ); // для удобства сдвигаем циклически новое значение на число бит.
std::cout << val << std::endl;
tmp = ( tmp & lmask ) | ( val & hmask ); // склеиваем хвост предыдущего элемента и младшую часть нового значения.
std::cout << tmp << std::endl;
*this->ptr = tmp.to_ulong (); // записываем в текущий элемент это значение.
tmp = *(this->ptr+1); // берем следующий элемент.
std::cout << tmp.to_ulong () << ":" << tmp << std::endl;
tmp = ( val & lmask ) | ( tmp & hmask ); // склеиваем старшую часть нового значения и начало следующего элемента.
std::cout << tmp << std::endl;
*(this->ptr+1) = tmp.to_ulong (); // записываем полученное значение в массив.return (*this);
}
};
int main() {
unsigned long x[4] = {7,5,3,5};
shift_iterator<2> it (x);
std::cout << it->value () << std::endl;
*it = std::numeric_limits<unsigned long>::max()-4;
return 0;
}
Предупреждаю сразу.
У итератора не хватает операций +,-, и операций сравнения. Добавить не сложно много но ручной работы.
bitset применял для наглядности. поэтому его лучше заменить непосредственно на value_type.
Здравствуйте, Аноним, Вы писали:
А>Есть массив элементов типа unsigned long int DI[100]; есть указатель на начало массива unsigned char *ptr; можно ...
Для реализации МодБас необязательно хранить ячейки в упакованном виде, хотя у меня кеш так и реализован, а можно в виде массива 32-х битных интежеров. Заодно получите возможность хранить неопределённые состояния.