2012-04-28 4 views
9

У меня есть массив символов, которые я пытаюсь поразрядно сдвинуть вправо >>, затем & с другим массивом. Я думаю, что у меня есть неправильное представление о том, как это сделать.Побитовое смещение массива char

я подумал, несмотря на то, что это был массив символов просто констатирует my_array >>= 1 перенесет все, но я получаю сообщение об ошибке: "error: invalid operands to binary >> (have ‘char[8]’ and ‘int’)"

Поразрядный Comparision Я пытаюсь сделать это с таким же массивом размера инициированного для всех «0» ... для этого я получаю: "error: invalid operands to binary & (have ‘char *’ and ‘char *’)"

Нужно ли мне преобразовать эти массивы во что-то еще, прежде чем я смогу сдвинуть и сравнить?

Извините, я не был предельно ясен ... Весь большой совет до этого момента, и я думаю, что понимаю, что нет супер простого способа сделать это. Более конкретно, то, что я пытаюсь сделать, это сдвинуть биты массива WHOLE char 1, добавив бит, сдвинутый с правой стороны влево на большую часть массива, поразрядное сравнение с другим массивом того же размера.

Технически сравнение не обязательно должно быть массивом с массивом ... Мне просто нужны биты. Было бы проще преобразовать массив в нечто другое, прежде чем пытаться выполнить сдвиги/сравнения?

+2

Вы пытаетесь повернуть содержимое массива или пытаетесь побитовое смещение каждого отдельного элемента массива? Ни одна из этих операций изначально не существует в C. Вам нужно будет написать цикл, который либо копирует каждый элемент в одно местоположение, либо побитовое смещает каждый элемент в массиве. – chrisaycock

ответ

10

Вы должны смещаться и сравнивать поэлементно.

for(i = 0; i < len; ++i) 
    array[i] >>= 3; 

например. Если вы хотите переместить биты сдвигаются одного элемента к другому, это сложнее, скажем, вы сдвигая вправо, то

unsigned char bits1 = 0, bits2 = 0; 
for(i = len-1; i >= 0; --i) { 
    bits2 = array[i] & 0x07; 
    array[i] >>= 3; 
    array[i] |= bits1 << 5; 
    bits1 = bits2; 
} 

обход массива в другом направлении, потому что нужны биты от следующего более высокий слот.

2

Вам придется перемещать записи в массиве по одному. (И если вы хотите сравнить два из них, вам нужно будет сделать это элемент за элементом.)

Если вы надеялись, что биты смещены, каждый символ переместится в следующий, вам нужно будет позаботьтесь об этом вручную.

Если вы хотите, чтобы это изменение в следующем-байте, и не прочь сделать ваш код неприятным и непереносимым и подверженным ошибкам, вы можете взять указатель на массив, бросить его на что-то вроде unsigned long long *, разыщите его и сдвиньте полученное целое число и сохраните его снова.

НО, если это то, что вы хотите, тогда вы должны использовать целое число вместо char[8] для начала.

(Если бы вы могли сказать больше о том, что вы на самом деле стремитесь достичь, то более полезных ответы могут быть возможны.)

2

Если вы хотите выполнять операции, такие как перемещение/OR/XOR/AND/etc .. на массивах, вы должны выполнить его в цикле, вы не можете выполнить его непосредственно в массиве.

2

Вы можете перемещать только элементы этих массивов, char (или int). Вы не можете переместить весь массив. Shifting my_array пытается выполнить операцию сдвига по типу массива (или указателю на символ), что невозможно.Сделайте это вместо того, чтобы:

for (i = 0; i < size; i++) { 
    my_array[i] >>= 1; 
} 

Кроме того, вы должны быть осторожны с гольцов, потому что они, как правило, подписаны, и символ, содержащий отрицательное значение принесет «1» с левой вместо нулей. Поэтому вам лучше использовать неподписанные символы.

EDIT: Этот код является упрощенным. Если вы намерены перенести массив в целом, а не только на каждый байт самостоятельно, тогда вам нужно «вручную» скопировать каждый LSB в MSB байта справа. Возьмите петлю в ответ Ричарда Пеннингтона.

+0

Я бы предположил, что он хочет рассматривать массив как одно значение, поэтому вам нужно будет нести бит из более значимого байта. – loganfsmyth

+0

Правильно, я отредактировал свой ответ. Спасибо –

3
/** Shift an array right. 
* @param ar The array to shift. 
* @param size The number of array elements. 
* @param shift The number of bits to shift. 
*/ 
void shift_right(unsigned char *ar, int size, int shift) 
{ 
    int carry = 0;        // Clear the initial carry bit. 
    while (shift--) {       // For each bit to shift ... 
     for (int i = size - 1; i >= 0; --i) { // For each element of the array from high to low ... 
      int next = (ar[i] & 1) ? 0x80 : 0; // ... if the low bit is set, set the carry bit. 
      ar[i] = carry | (ar[i] >> 1);  // Shift the element one bit left and addthe old carry. 
      carry = next;      // Remember the old carry for next time. 
     } 
    } 
} 
+0

Ну, это выглядит странно, или я чего-то не хватает. Это похоже на сочетание сдвига вправо и сдвиг влево. Комментарий рядом с битом переноса говорит: «Сдвиньте элемент на один бит слева», но он сдвинется вправо. И цикл for будет высоким до минимума, я предпочел бы перейти к максимуму для правильного переключения. –

+0

Также я бы переместил «int carry = 0;» внутри цикла while перед циклом for. –