Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/29: Рейтинг темы: голосов - 29, средняя оценка - 4.55
3 / 3 / 0
Регистрация: 02.03.2013
Сообщений: 56
1

Создать структуру для работы с битами

11.09.2014, 17:31. Показов 5498. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем добра
Есть такая проблемка, сейчас постараюсь описать её. Допустим есть целое число типа int. И пусть оно длиной 16 бит.
в двоичном представлении оно наверяка будет выглядеть так (если оно равно 0)
0000 0000 0000 0000. биты нумерутся от 0 до 15

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

C
1
2
3
4
5
6
7
8
9
10
typedef struct
{
  Поле1 : меняет биты с 0 до 7 (допустим сюда можно записать 8 битное число)
  Поле2 : меняет 8-й бит
  Поле3 : меняет 9-й и 10-й бит
  Поле4 : меняет 11-й бит
  Поле5 : меняет 12-й и 13-й бит
  Поле6 : меняет 14-й бит 
  /** 15-й бит допустим не используется */
} STRUCT;
и чтобы её можно было применять так

C
1
2
3
4
5
6
STRUCT.Поле1 = Какая_то_переменная_размеромм_8_бит /** например значение её 0011 1101 */
STRUCT.Поле2 = ENABLE; /** как-то опредлить ENABLE и DISABLE как 1 и 0 */
STRUCT.Поле3 = /** сюда как-нибудь записать два бита, например 01 */
STRUCT.Поле4 = DISABLE;
STRUCT.Поле5 = /** сюда опять как-нибудь записать два бита, например 11 */
STRUCT.Поле6 = ENABLE;
и после этих манипуляций должны записаться все биты, которые мы записывали через поля, т.е. результат такой
00111101 1 01 0 11 1 0
пробелами выделила Поля, первая цепочка цифр (00111101) это Поле1, вторая (1) - это Поле2 и т.д. Но если я не использую какие-нибудь поля, то на месте этих битов ничего не записывается

догадываюсь, что надо использовать побитовые операции сдвига и прочие побитовые штуковины, но как реазлизовать такое - незнаю..

если кто сможет, то помогите пожалуйста
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.09.2014, 17:31
Ответы с готовыми решениями:

Создать структуру для работы с квадратом
Создать структуру для работы с квадратом. Создать конструктор ввода данных. Создать методы: -...

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

Создать структуру для работы с датой
Создать на С++ структуру для работы с датой. Данные структуры: день, месяц, год. Создать функции:...

Создать структуру Money для работы с денежными суммами
Люди, помогите, пожалуйста! Есть задача: Создать структуру Money для работы с денежными суммами....

20
И целого heap'а мало
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
11.09.2014, 18:00 2
Мега Ксю, предлагаю заюзать битовые маски.
0
430 / 384 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
11.09.2014, 18:11 3
Поддерживаю предыдущего оратора. А еще проще использовать нормальную структуру, примерно вот так:

C
1
2
3
4
5
6
7
8
typedef struct MyStruct {
    int field1;
    int field2;
    int field3;
    int field4;
    int field5;
    int field6;
} *MyStruct;
В подавляющем количестве случаев вся эта грошовая экономия на битах не имеет никакого смысла. Ну будешь ты использовать 6 Килобайт вместо одного, например. Какой ужос! Компьютер - не лошадь, поди не надорвется.
0
76 / 36 / 17
Регистрация: 24.07.2014
Сообщений: 357
11.09.2014, 18:44 4
Цитата Сообщение от Vtulhu Посмотреть сообщение
В подавляющем количестве случаев вся эта грошовая экономия на битах не имеет никакого смысла. Ну будешь ты использовать 6 Килобайт вместо одного, например. Какой ужос! Компьютер - не лошадь, поди не надорвется.
судя по тому что именно Си, задача наверное на микроконтроллер а он надорватся может.Мега Ксю, я правильно догадался?
0
3 / 3 / 0
Регистрация: 02.03.2013
Сообщений: 56
11.09.2014, 19:41  [ТС] 5
Цитата Сообщение от Vtulhu Посмотреть сообщение
В подавляющем количестве случаев вся эта грошовая экономия на битах не имеет никакого смысла. Ну будешь ты использовать 6 Килобайт вместо одного, например. Какой ужос! Компьютер - не лошадь, поди не надорвется
тут как раз такой случай, когда может надорваться в моём распоряжении 16КБ (да да, именно Килобайта) оперативной памяти, это будет описание регистра для микроконроллера.
Справлюсь, да, вы абсолютно правы

Добавлено через 1 минуту
Andrej, а как их заюзать? можете примерчик бросить для моего случая?
0
И целого heap'а мало
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
11.09.2014, 19:59 6
Мега Ксю, http://www.rfe.by/media/kafedr... ija-18.pdf там Битовые поля структур.
Там говорится, можно заименовать последовательность бит в структуре (даже один нанобитик) и обращаться к ним.
А битовые маски оказались немного из другой оперы.

Не по теме:

Понесло же вас в микроконтроллеры. :)

1
153 / 148 / 66
Регистрация: 20.02.2014
Сообщений: 556
11.09.2014, 20:04 7
Лучший ответ Сообщение было отмечено Мега Ксю как решение

Решение

Мега Ксю, если возможно и поддерживается, то как вариант битовые поля и объединения.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <limits.h>
 
#define ENABLE      0x01
#define DISABLE     0x00
 
typedef union {
    short field;
    struct {
        unsigned field1:8;
        unsigned field2:1;
        unsigned field3:2;
        unsigned field4:1;
        unsigned field5:2;
        unsigned field6:1;
    } fields;
} STRUCT;
 
void print(unsigned short n) {
    for(int i = sizeof(short) * CHAR_BIT - 1; i >= 0; --i) {
        printf("%d%s", n&(1 << i) ? 1 : 0, i%4 ? "" : " ");
    }
    printf("\n");
}
 
int main(void) {
    STRUCT st = {0};
    print(st.field);
    st.fields.field1 = 0xAA;
    print(st.field);
    st.fields.field2 = ENABLE;
    print(st.field);
    st.fields.field3 = 0x01;
    print(st.field);
    st.fields.field4 = DISABLE;
    print(st.field);
    st.fields.field5 = 0x03;
    print(st.field);
    st.fields.field6 = ENABLE;
    print(st.field);
 
    return 0;
}
1
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
11.09.2014, 20:06 8
Цитата Сообщение от Мега Ксю Посмотреть сообщение
, это будет описание регистра для микроконроллера.
вопрос какого?
даташит прочитай
многие конторллеры, например 51 серия, позволяют работать с отдельными битами, и сами их упаковывают в байт
но не во всем адресном пространстве
0
3 / 3 / 0
Регистрация: 02.03.2013
Сообщений: 56
11.09.2014, 23:53  [ТС] 9
Вованя, спасибо большое
кто-нибудь может объяснить эти две строчки
C
1
2
for (int i = sizeof(short)* CHAR_BIT - 1; i >= 0; --i)
  printf("%d%s", n&(1 << i) ? 1 : 0, i % 4 ? "" : " ")
"синтаксически" понимаю что тут (там всякие сдвиги на i, и пр.), но что именно в них происходит в "железе"?
точнее интересуют кусочки
C
1
n&(1 << i)
и этот
C
1
int i = sizeof(short)* CHAR_BIT - 1
Добавлено через 3 минуты
насчёт этого,
C
1
n&(1 << i)
то думаю что это возвратит бит на позиции i в числе n. Если я верно думаю, то как мне сделать обратную задачу, т.е. записать бит на позиции i в числе n?

Добавлено через 6 минут
и ещё вопросик
могу ли я как-нибудь обойтись без этой структуры?
C
1
2
3
4
5
6
7
8
9
10
11
typedef union {
    short field;
    struct {
        unsigned field1:8;
        unsigned field2:1;
        unsigned field3:2;
        unsigned field4:1;
        unsigned field5:2;
        unsigned field6:1;
    } fields;
} STRUCT;
точнее, не то, чтобы прям совсем без неё, а использовать такую
C
1
2
3
4
5
6
7
8
typedef struct {
  unsigned field1:8;
  unsigned field2:1;
  unsigned field3:2;
  unsigned field4:1;
  unsigned field5:2;
  unsigned field6:1;
} STRUCT;
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
12.09.2014, 00:15 10
Цитата Сообщение от Мега Ксю Посмотреть сообщение
n&(1 << i)
сдвинуть 1 на i вправо и операция "И"
выделить i-тый бит
например
i=2 n=5(0000 0101)
1 << i(1 << 2)= 4(0000 0100)
5&4=4 (0000 0101&0000 0100=0000 00100)
Цитата Сообщение от Мега Ксю Посмотреть сообщение
int i = sizeof(short)* CHAR_BIT - 1
sizeof(short) размер short в байтах(обычно 2)
CHAR_BIT количество бит в байте (обычно 8)
итого sizeof(short)* CHAR_BIT=16
и (1 << i) сдвинет на 16 позиций, но нужно на 15(старший бит у short 15тый), посему и -1

Добавлено через 8 минут
Цитата Сообщение от Мега Ксю Посмотреть сообщение
могу ли я как-нибудь обойтись без этой структуры?
это не структура это объедение(union)
т.е одно и тоже значение по определенному адресу можно считать и как short и как битовое поле
например
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef union {
    short field;
    struct {
        unsigned field1:8;
        unsigned field2:1;
        unsigned field3:2;
        unsigned field4:1;
        unsigned field5:2;
        unsigned field6:1;
    } fields;
} STRUCT;
 
STRUCT a;
a.field=0;
short b=a.field;// в b 0
a.fields[5]=2;
short c=a.field;// в c 4(0000 0000 0000 0100)
1
430 / 384 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
12.09.2014, 00:18 11
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
unsigned get_field1(unsigned x)
{
    x &= 0x00FF;
    return x;
}
 
void set_field1(unsigned x, unsigned n)
{
    n &= 0x00FF;
    x &= 0xFF00;
    x += n;
    return x;
}
 
unsigned get_field2(unsigned x)
{
    x &= 0x0100;
    return !!x;
}
 
void set_field2(unsigned x, unsigned n)
{
     if( n == 0 ) {
         x &= 0xFEFF;
     } else {
         x |= 0x0100;
     }
     return x;
}
 
unsigned get_field3(unsigned x)
{
    x >>= 9;
    x &= 0x0003;
    return x;
}
 
void set_field3(unsigned x, unsigned n)
{
    n &= 0x0003;
    n <<= 9;
    x &= F9FF;
    x += n;
    return x;
}
1
3 / 3 / 0
Регистрация: 02.03.2013
Сообщений: 56
12.09.2014, 08:58  [ТС] 12
ValeryS, спасибо большое!
Если я вас правильно поняла, то эта задача
Цитата Сообщение от Мега Ксю Посмотреть сообщение
как мне сделать обратную задачу, т.е. записать бит на позиции i в числе n?
будет решена так
C
1
2
int a = 0;
a & (1 << 5) = 1
т.е. тут я установлю в числе a 5-й бит в единичку?

Vtulhu, я правильно поняла, что тип unsigned это бит?
и если не сложно, то можете объяснить, что значат эти строчки?
C
1
2
3
4
n &= 0x00FF;
    x &= 0xFF00;
  ***
    x |= 0x0100;

Не по теме:

а контроллер не будут загружать (в плане производительности) там всякие эти объединения?



Добавлено через 2 минуты

Не по теме:

извиняюсь, что задаю слишком много вопросов, но я только начинаю программировать на C, и с такими низкоуровневыми штучками в первый раз столкнулась...

0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
12.09.2014, 09:27 13
Цитата Сообщение от Мега Ксю Посмотреть сообщение
будет решена так
нет
вот так
C
1
a=a|(1<<5);
или так
C
1
a|=(1<<5);
Цитата Сообщение от Мега Ксю Посмотреть сообщение
я правильно поняла, что тип unsigned это бит?
нет unsigned это значит беззнаковый, в отличии от signed знаковый
т.е старший бит интерпретируется как знак (signed) или часть числа(unsigned)
Цитата Сообщение от Мега Ксю Посмотреть сообщение
а контроллер не будут загружать (в плане производительности) там всякие эти объединения?
не будет когда программа скомпилится от всех этих объединений и следа не останется
Цитата Сообщение от Мега Ксю Посмотреть сообщение
извиняюсь, что задаю слишком много вопросов, но я только начинаю программировать на C,
почитай что такое битовые операции "И", "ИЛИ", "НЕ", "ИСКЛЮЧАЮЩИЕ ИЛИ"
без этого для микроконтроллеров трудно писать
1
3 / 3 / 0
Регистрация: 02.03.2013
Сообщений: 56
15.09.2014, 08:06  [ТС] 14
ValeryS, спасибо большое
если вы меня не побьёте, то можно ещё вопросик?
вот если есть вот такое объединение
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef union {
    short field;
    struct {
        unsigned field1:8;
        unsigned field2:1;
        unsigned field3:2;
        unsigned field4:1;
        unsigned field5:2;
        unsigned field6:1;
    } fields;
} STRUCT;
 
STRUCT a;
a.field=0;
short b=a.field;// в b 0
a.fields[5]=2;
short c=a.field;// в c 4(0000 0000 0000 0100)
я могу как-нибудь сделать так, чтобы при использовании не создавать эту переменную
C
1
STRUCT a;

просто я эту тему начала по сути из-за такого вопроса, что хочу обращаться к регистрам следующие образом
C
1
ИмяРегистра.ИмяПоля = Значение
без всяких прочих манипцляций
Можно ли так сделать?
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
16.09.2014, 06:50 15
Цитата Сообщение от Мега Ксю Посмотреть сообщение
я могу как-нибудь сделать так, чтобы при использовании не создавать эту переменную
Нет
Для того чтобы к чему нибудь обратится нужно это что то иметь
STRUCT это описание, и все
а
Цитата Сообщение от Мега Ксю Посмотреть сообщение
STRUCT a
a это уже объект который имеет тип STRUCT
Цитата Сообщение от Мега Ксю Посмотреть сообщение
просто я эту тему начала по сути из-за такого вопроса, что хочу обращаться к регистрам следующие образом
Регистры это что?
какая то абстракция или конкретные места в памяти
если конкретные места, то пользуйся приведением типов
посмотри исходники например для stm32f..... там этих приведений куча

Не по теме:

Цитата Сообщение от Мега Ксю Посмотреть сообщение
если вы меня не побьёте,
Так вроде, не что, пока :scratch: :)
"Любопытство не порок, а такое хобби"(с)

0
3 / 3 / 0
Регистрация: 02.03.2013
Сообщений: 56
17.09.2014, 14:32  [ТС] 16
Цитата Сообщение от ValeryS Посмотреть сообщение
Так вроде, не что, пока
ну если пошли такие дела, то позволю себе ещё несколько вопросиков

вот так можно будет сделать?
C
1
2
3
4
5
6
7
8
9
10
11
typedef union STRUCT {
    short field;
    struct {
        unsigned field1:8;
        unsigned field2:1;
        unsigned field3:2;
        unsigned field4:1;
        unsigned field5:2;
        unsigned field6:1;
    } fields;
} *st; /** тут как-то надо указать на адрес в памяти, например 0x0001 */
Цитата Сообщение от ValeryS Посмотреть сообщение
Регистры это что?
какая то абстракция или конкретные места в памяти
это конкретные места, есть их адреса
Цитата Сообщение от ValeryS Посмотреть сообщение
если конкретные места, то пользуйся приведением типов
хорошо я постараюсь посмотреть, если я сама смогу найти там эти привидения

Не по теме:

Цитата Сообщение от ValeryS Посмотреть сообщение
"Любопытство не порок, а такое хобби"(с)
Порой мне кажется, что за такое хобби меня кто-нибудь покусает когда-нибудь:gsmile:

0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
18.09.2014, 09:13 17
Цитата Сообщение от Мега Ксю Посмотреть сообщение
*st; /** тут как-то надо указать на адрес в памяти, например 0x0001 */
если адрес известен то ничего сложного
C++
1
st=0x0001;
по правильному еще и приводить нужно, например
C++
1
st=(STRUCT * )0x0001;
Мега Ксю, скажи с каким контроллером работать хочешь? может и не нужно будет всего этого.
при работе с контроллером, достаточно низкоуровневое программирование, нужно очень хорошо понимать его архитектуру
и примочки, которые срабатываю на АВР, не сработают на АРМ
1
3 / 3 / 0
Регистрация: 02.03.2013
Сообщений: 56
22.09.2014, 22:57  [ТС] 18
ValeryS, извиняюсь, что долго не отвечала..
если я вас правильно поняла, то могу писать так
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
typedef union STRUCT {
    short field;
    struct {
        unsigned field1:8;
        unsigned field2:1;
        unsigned field3:2;
        unsigned field4:1;
        unsigned field5:2;
        unsigned field6:1;
    } fields;
} st = (STRUCT *) 0x0001;
 
int main(void)
{
/** тут код всякий */
 
/** и использую так */
st.fields.field1 = (uint8_t) 0x00;
return 0;
}
я правильно поняла?

Не по теме:

Работаю (точнее пытаюсь работать:gsmile: ) с отечественным контроллером К1986ВЕ91Т, это ARM-контроллер с ядром Cortex-M3

0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
23.09.2014, 06:32 19
Цитата Сообщение от Мега Ксю Посмотреть сообщение
то могу писать так
да
но с этим не вяжется
Цитата Сообщение от Мега Ксю Посмотреть сообщение
это ARM-контроллер
у АРМов шаг обычно кратен четырем или 2 (тумп режим)

Цитата Сообщение от Мега Ксю Посмотреть сообщение
с отечественным контроллером К1986ВЕ91Т,
никогда не сталкивался ничем не могу пока помочь
дай ссылку на даташит, тогда поговорим поконкретней

это белорусы?
1
3 / 3 / 0
Регистрация: 02.03.2013
Сообщений: 56
23.09.2014, 10:58  [ТС] 20
Цитата Сообщение от ValeryS Посмотреть сообщение
но с этим не вяжется
т.е. для arm-контроллера я так программировать не смогу?
Цитата Сообщение от ValeryS Посмотреть сообщение
с отечественным контроллером К1986ВЕ91Т
http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=13&cntnt01returnid=68
Цитата Сообщение от ValeryS Посмотреть сообщение
дай ссылку на даташит, тогда поговорим поконкретней
она тут же, на официальном сайте http://milandr.ru/index.php?ma... eturnid=68
или вот прямая ссылка на него
http://milandr.ru/uploads/Prod... 86BE9x.pdf

Цитата Сообщение от ValeryS Посмотреть сообщение
это белорусы?
нет, это г. Зеленоград, Россия

Добавлено через 4 минуты
и ещё, когда смотрела исходники всякие, то там использовалось просто union, вместо typedef union
можете в двух словах сказать, в чем отличие этой записи
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
typedef union STRUCT {
    short field;
    struct {
        unsigned field1:8;
        unsigned field2:1;
        unsigned field3:2;
        unsigned field4:1;
        unsigned field5:2;
        unsigned field6:1;
    } fields;
} st = (STRUCT *) 0x0001;
 
int main(void)
{
/** тут код всякий */
 
/** и использую так */
st.fields.field1 = (uint8_t) 0x00;
return 0;
}
от этой
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
union STRUCT {
    short field;
    struct {
        unsigned field1:8;
        unsigned field2:1;
        unsigned field3:2;
        unsigned field4:1;
        unsigned field5:2;
        unsigned field6:1;
    } fields;
} st = (STRUCT *) 0x0001;
 
int main(void)
{
/** тут код всякий */
 
/** и использую так */
st.fields.field1 = (uint8_t) 0x00;
return 0;
}
0
23.09.2014, 10:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.09.2014, 10:58
Помогаю со студенческими работами здесь

Создать структуру окружность и методы для работы с ней
Создайте структуру Окружность с элементами х0, у0- координаты центра, R -радиус. Для N...

Создать структуру Абитуриент и написать программу для работы с ней
Прошу помочь с решением задачи. Опишите,используя структуру записи,конкурс на поступление(фамилия...

Создать структуру, описывающую человека и класс для работы с данными о людях
Создать структуру, описывающую человека (ФИО, возраст, пол, страна). Создать класс для работы с...

операции для работы с битами
Есть ли в Visual C++ операторы выполняющие операции для работы с битами(сдвиг влево, сдвиг вправо,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru