Есть ли способ получить доступ к отдельным битам с помощью объединения?

Вы должны определить элемент DOM контейнера в стилях CSS следующим образом:

  1. display: flex;
  2. align-items: center; (вертикально по центру)
  3. justify-content: center; (По горизонтали)

Например:

div.v-center-container {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 4em;
  border: 1px solid black;
}
<div class="v-center-container">
<div>This is vertically center strings</div>
</div>

Каждая вещь в DOM элемент с классом v-center-container будет автоматически выравниваться по вертикали.

16
задан timrau 15 August 2012 в 17:06
поделиться

6 ответов

Конечно, но вы действительно хотите использовать структуру для определения битов, подобных этой

typedef union
{
  struct
  {
    unsigned char bit1 : 1;
    unsigned char bit2 : 1;
    unsigned char bit3 : 1;
    unsigned char bit4 : 1;
    unsigned char bit5 : 1;
    unsigned char bit6 : 1;
    unsigned char bit7 : 1;
    unsigned char bit8 : 1;
  }u;
  unsigned char status;
}DeviceStatus;

Затем вы можете получить доступ к DeviceStatus ds; вы можете получить доступ к ds .u.bit1 . Кроме того, некоторые компиляторы фактически позволяют вам иметь анонимные структуры в объединении, так что вы можете просто получить доступ к ds.bit1 , если вы опустите u в typedef.

22
ответ дан 30 November 2019 в 17:51
поделиться

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

int bit0 = 1;
int bit1 = 2;
int bit2 = 4;
int bit3 = 8;
int bit4 = 16;
int bit5 = 32;
int bit6 = 64;
int bit7 = 128;

if (status & bit1)
    // whatever...

Другой - использовать битовые поля:

struct bits { 
   unsigned bit0 : 1;
   unsigned bit1 : 1;
   unsigned bit2 : 1;
// ...
};

typedef union {
    unsigned char status;
    struct bits bits;
} status_byte;

some_status_byte.status = whatever;
if (status_byte.bits.bit2)
    // whatever...

Первый (по крайней мере, возможно) более переносим, ​​но когда вы имеете дело с битами состояния, есть вероятность, что код в любом случае даже не является немного переносимым, поэтому вы можете не заботиться об этом ...

4
ответ дан 30 November 2019 в 17:51
поделиться

Как уже было сказано, вы не можете адресовать память размером менее байта в C. Я написал бы макрос:

#define BIT(n) (1 << n)

и использовал бы его для доступа к битам. Таким образом, ваш доступ будет одинаковым, независимо от размера структуры, к которой вы обращаетесь. Вы бы написали свой код следующим образом:

if (status & BIT(1)) {
   // Do something if bit 1 is set
} elseif (~status | BIT(2) {
   // Do something else if bit 2 is cleared
} else  {
   // Set bits 1 and 2
   status |= BIT(1) | BIT(2)
   // Clear bits 0 and 4
   status &= ~(BIT(0) | BIT(4))
   // Toggle bit 5 
   status ^= BIT(5)
}

Это позволит вам получить доступ близко к вашей предложенной системе, которая будет использовать [] вместо ().

3
ответ дан 30 November 2019 в 17:51
поделиться
typedef union
{
  unsigned char status;
  struct bitFields
  {
    _Bool bit0 : 1;
    _Bool bit1 : 1;
    _Bool bit2 : 1;
    _Bool bit3 : 1;
    _Bool bit4 : 1;
    _Bool bit5 : 1;
    _Bool bit6 : 1;
    _Bool bit7 : 1;
  } bits;
}DeviceStatus;
1
ответ дан 30 November 2019 в 17:51
поделиться

Наименьшая единица, адресуемая в C, всегда является байтом (в C он называется char). Вы не можете получить доступ к биту напрямую. Ближайшим способом получить доступ к битам будет определение типа данных под названием bitpointer и определение некоторых функций или макросов для него:

#include <stdbool.h>

typedef struct bitpointer {
    unsigned char *pb; /* pointer to the byte */
    unsigned int bit; /* bit number inside the byte */
} bitpointer;

static inline bool bitpointer_isset(const bitpointer *bp) {
    return (bp->pb & (1 << bp->bit)) != 0;
}

static inline void bitpointer_set(const bitpointer *bp, bool value) {
    unsigned char shifted = (value ? 1 : 0) << bp->bit;
    unsigned char cleared = *bp->pb &~ (1 << bp->bit);
    *(bp->pb) = cleared | shifted;
}

Я не рекомендую использовать союзы, потому что это зависит от реализации, заполняются ли они msb-to-lsb или lsb-to-msb (см. ISO C99, 6.7.2.1p10).

0
ответ дан 30 November 2019 в 17:51
поделиться

Вы можете сделать это, поместив биты в структуру внутри объединения, но это может или не может работать, в зависимости от вашей реализации. В определении языка не указывается, в каком порядке отдельные биты будут сопоставляться с битами unsigned char ; хуже того, это даже не гарантирует, что биты будут перекрываться с unsigned char (компилятор может решить разместить отдельные биты в сторону наиболее значимой части слова и unsigned char ] в сторону наименее значимой стороны или наоборот).

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

#define FLAG_BUSY 0x01
#define FLAG_DATA_AVAILABLE 0x02
#define FLAG_TRANSMISSION_IN_PROGRESS 0x04
...
#define FLAG_ERROR 0x80

Затем для чтения и записи отдельных битов:

if (status & FLAG_BUSY) ... /* test if the device is busy */
status &= ~FLAG_ERROR; /* turn off error flag */
status |= FLAG_TRANSMISSION_IN_PROGRESS /* turn on transmission-in-progress flag */
0
ответ дан 30 November 2019 в 17:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: