2014-10-09 2 views
0

У меня возникли проблемы с выяснением того, как манипулирующие биты работают с C. Интересно, может ли кто-нибудь что-то прояснить для меня.Не удалось манипулировать битами с помощью C

Эти функции у меня есть для набора/получить/очистить бит

unsigned char getBit(unsigned char c, int n) 
{ 
    (c & (1<<n)) >> c; 
    return c; 
} 

unsigned char setBit(unsigned char c, int n) 
{ 
    c = c |(1<<n); 
    return c; 
} 

unsigned char clearBit(unsigned char c, int n) 
{ 
    c = c & (~1<<n); 
    return c; 
} 

и скажем, у меня есть unsigned char test = 3 в двоичной, 3 0000 0011

Так что, если бы я сделать printf("THIS IS THE VALUE AT BIT 0 = %hhu \n", getBit(test, 0)); Я думаю, что он вернется обратно 1, но вместо этого он возвращает значение test, которое 3.

мне было интересно, если я делаю что-то ж rong, мои функции get/set/clear кажутся правильными, я не правильно использую функции?

Заранее спасибо.

+0

В какой момент 'getBit' изменить значение' c'? – Gabe

+0

И почему он сдвигается на 'c' вместо некоторой функции' n'? –

+0

getBit не должен менять значение c, он должен найти бит значение c, в n-й позиции. – johnnyboyyy

ответ

0
(c & (1<<n)) >> c 

это выражение, которое не изменениеc вообще. Это примерно так же полезно, как и утверждение:

42; 

Вы должны измененияc если вы хотите, чтобы вернуть его, с чем-то сродни:

c = (c & (1<<n)) >> c; 

или простой:

c = (c >> 1) & 1; 

Вы уже отлично справляетесь с setBit и clearBit, вам просто нужно адаптировать getBit.

Кроме того, ваш clearBit не будет работать, так как порядок действий неверен. Оператор << сдвигается в ноль бит с правой стороны, так что (~1<<4) на самом деле двоичный 11100000, а не 11101111. Вместо этого вы должны обеспечить сдвиг выполняется до того бита инверсии:

c = c & ~(1 << n); 

И, так как я беру минималистский подход к коду, я бы, вероятно, канавы «изменить c и вернуть его» стратегия для чего-то более простого:

unsigned char getBit(unsigned char c, int n) { 
    return (c >> n) & 1; 
} 

unsigned char setBit(unsigned char c, int n) { 
    return c | (1 << n); 
} 

unsigned char clearBit(unsigned char c, int n) { 
    return c & ~(1 << n); 
} 

и помните, что вы возвращения измененное значение для setBit и clearBit, поэтому у вас есть присвоить его с чем-то вроде:

unsigned char xyzzy = 0; 
xyzzy = setBit (xyzzy, 3); 
+0

Поскольку * 42 * является ответом на все, что будет следовать за тем, что программа будет делать правильные действия после этого утверждения. К сожалению, большинство компиляторов оптимизирует его, не понимая, что '42;' имеет побочные эффекты ;-). –

+0

Благодарим вас за исправление функций для меня! Мне было интересно, как правильно использовать функции clearBit и setBit. Должен ли я делать getBit (test, 0) = clearBit (test, 0), или я могу просто объявить clearBit (test, 0); Я пытаюсь в обоих направлениях, но значения по-прежнему остаются на 1. – johnnyboyyy

+0

nevermind! Он работал после doign 'key = clearBit (key, 0);' Я предполагаю, что это правильный способ сделать это. – johnnyboyyy

1

Сделать это просто сдвигая бит вы хотите на 1-й позиции:

unsigned char getBit(unsigned char c, int n) 
{ 
    return (c >> n) & 1; 
} 
Смежные вопросы