Прежде всего, я собираюсь предположить, что вы не планируете выполнять эти операции последовательно в одной операции. Если вы действительно сделаете это, результат всегда будет 0xff
, независимо от ввода, поэтому вам не нужно разбираться с вводом, разбивая его на поля или многое другое. Итак, я собираюсь предположить, что если пара битов на входе начиналась с 00, то конечный результат для этого поля должен быть 01, аналогично, если это было 01, оно должно заканчиваться как 10, а если это было 10, это должно в итоге получится 11 (потом, вы можете вызвать его снова, чтобы каждый делал следующий шаг и т. д.).
Во-вторых, я хочу отметить, что эти операции аналогичны простому приращению 2 -битное поле. То есть: 0-> 1, 1-> 2, 2-> 3 (и 3, мы, вероятно, оставим в покое, хотя вы не указали).
Один простой способ добраться до нескольких бит в тип данных C должен использовать поддержку битовых полей. В этом случае мы будем использовать его вместе с объединением, поэтому у нас есть один член объединения, который дает нам доступ к отдельным полям, а другой - ко всему байту как к единице.
#include <stdio.h>
// depending on how new it is, your compiler may already define this:
typedef unsigned char uint8_t;
struct Foo {
uint8_t a : 2;
uint8_t b : 2;
uint8_t c : 2;
uint8_t d : 2;
};
typedef union {
unsigned char whole;
struct Foo parts;
} val;
Так что теперь, когда у нас есть доступ к частям, давайте напишем небольшой код, чтобы продемонстрировать его использование:
int main(void) {
val a = {.whole = 0xe4};
// replacing 00 with 01, 01 with 10 and 10 with 11 is incrementing, except for 11
if (a.parts.a < 3)
++a.parts.a;
if (a.parts.b < 3)
++a.parts.b;
if (a.parts.c < 3)
++a.parts.c;
if (a.parts.d < 3)
++a.parts.d;
printf("%2.2x\n", a.whole);
}
Предупреждение: теоретически, запись в одно поле объединения, а затем чтение из другого не дает определенных результатов. В действительности, однако, код, который взаимодействует с оборудованием, делает подобные вещи довольно регулярно. Что меняется, так это порядок - будь то (например) a.parts.a
младший или более значащий бит в a.whole
. К сожалению, это может варьироваться не только в зависимости от платформы, но и между разными компиляторами на одной платформе. С другой стороны, в вашем случае это просто не имеет значения.