C: Является ли этот фрагмент кода правильным для сдвига влево массива символов, сохранения «n-го» бита и установки 0-го бита как 0 или 1 на основе условия?

#c

#c

Вопрос:

Я должен сделать эту программу, в которой я должен использовать регистр, длина которого может составлять от 1 до 20 бит. я мог думать только об использовании массива символов для этой цели. Я хочу сдвинуть влево (на 1), сбросить n-й бит и установить или сбросить 0-й бит в зависимости от условия. Поскольку я не знаю количество битов до момента выполнения, я использую using malloc для выделения размера массива символов. Пожалуйста, скажите мне, правильно ли это

 // history bits can change from 1 to 20
int historyRegisterSize=(historybits 7)/8;

// allocating memory dynamically
historyRegister=malloc(historyRegisterSize * sizeof(unsigned char));

// Shifting left one bit
    unsigned char *byte;
    int size=historyRegisterSize;
    for( byte =historyRegister; size--;   byte )
    {
        unsigned char bit = 0;
        if (size>=0)
        {
            bit = byte[1] amp; (1 << (8 - 1)) ? 1 : 0;
        }
        *byte <<= 1;
        *byte |= bit;
    }

    // Resetting the nth bit 
    historyRegister[0]=historyRegister[0] amp; 0x7;

     // or should i use this one for resetting?
     //historyRegister[historyRegisterSize-1] amp;= ~(1 <<(historybits-1));

    // Setting the 0th bit based on a condition
    if(condition)
    {
        historyRegister[historyRegisterSize-1]=historyRegister[historyRegisterSize-1] | 1;
        // or should i use this statement below?
        //historyRegister[0] |= 1 <<0;
    }
    else
    {
    historyRegister[historyRegisterSize-1]=historyRegister[historyRegisterSize-1] amp; 0xfe;
      // or should i use this statement below?
      //historyRegister[0] amp;= ~(1 <<0);
    }
 

После выполнения всего этого я хочу XOR 64-разрядное целое число без знака с моим массивом символов (historyRegister) и взять его модуль. Для этого я использую это утверждение

 // result and var2 and unsigned long variables 
// and size is another unsigned integer.
result=(var1 ^ *(unsigned long int *)historyRegister) % size; 
 

Все кажется правильным? Моя проблема заключается в том, что когда я изменяю количество битов в массиве символов, выходные значения, по-видимому, остаются постоянными для определенного диапазона. То есть от 1 до 8 бит — это один и тот же o / p, от 8 до 16, а затем от 16 до 20. Я что-то не так делаю с порядковым номером?

Кроме того, есть ли лучшая альтернатива использованию массива символов?

Комментарии:

1. Если я правильно понимаю, каждый «регистр» имеет длину до 20 бит. Но a char имеет только 8 бит. Значит, вам понадобится больший тип данных?

Ответ №1:

Если вам нужно сохранить только 20 бит, было бы проще использовать unsigned int или long . Затем смещение может быть выполнено с помощью

 val <<= 1;
 

Вы могли бы замаскировать крайние левые биты с помощью

 val amp;= ((1u <<n) -1);
 

Комментарии:

1. не могли бы вы сказать мне, что такое «1u» в операторе? как мне изменить его, чтобы сбросить только определенный бит в длинной переменной без знака?

2. 1u просто «приводится как литеральное приведение к неподписанному типу». Это может быть излишним, но это (хорошо?) привычка выполнять все операции с битовыми масками для неподписанных типов.