Обычно (игнорируя битовые поля) C не может хранить ничего меньше, чем char
.Чтобы обойти это, вы можете прочитать целое char
, изменить его часть, а затем сохранить целое (измененное) char
.
. Обратите внимание, что в C char
может быть подписано (например, может бытьоктет со знаком в диапазоне от -128 до +127);и это делает беспорядочным изменение из-за неопределенности (например, поведение «сдвига вправо от целого числа со знаком» не определено).По этой причине я настоятельно рекомендую использовать unsigned char
или uint8_t
.
Чтобы написать наименьший клев, вы хотели бы сделать что-то вроде:
dest = dest & 0xF0; // Clear all bits in the low nibble
dest = dest | new_nibble; // Set new bits in the low nibble
Чтобы написать наивысшийКлев, вы хотите сделать что-то вроде:
dest = dest & 0x0F; // Clear all bits in the high nibble
dest = dest | (new_nibble << 4); // Set new bits in the high nibble
Чтобы прочитать клев, вы должны сделать что-то вроде:
low_nibble = src & 0x0F;
high_nibble = (src & 0xF0) >> 4;
Копирование это просто чтение, а затем запись.Например, чтобы скопировать самый младший клочок из src
в верхний клочок в dest
, вы можете:
nibble = src & 0x0F;
dest = dest & 0x0F; // Clear all bits in the high nibble
dest = dest | (nibble << 4); // Set new bits in the high nibble
С элементами массивов это может выглядеть так:
nibble1 = input[loop] & 0x0F;
nibble2 = (input[loop] & 0xF0) >> 4;
gen_message[loop + 1] = gen_message[loop + 1] & 0xF0;
gen_message[loop + 1] = gen_message[loop + 1] | nibble1;
gen_message[loop] = gen_message[loop] & 0x0F;
gen_message[loop] = gen_message[loop] | (nibble2 << 4);
Это также может быть сделано более кратко:
gen_message[loop + 1] &= 0xF0;
gen_message[loop + 1] |= input[loop] & 0x0F;
gen_message[loop] &= 0x0F;
gen_message[loop] |= ((input[loop] & 0xF0) >> 4) << 4;
Конечно, если вы знаете, что пункт назначения уже содержит нули (например, из-за memset()
или calloc()
), вы можете пропустить части "clear nibble":
gen_message[loop + 1] |= input[loop] & 0x0F;
gen_message[loop] |= ((input[loop] & 0xF0) >> 4) << 4;
РЕДАКТИРОВАТЬ
Другие комментаторы правы - из-за множества проблем трудно угадать, что вы на самом деле пытаетесь сделать.Я думаю, что вы можете (но не можете) пытаться сделать что-то вроде этого:
unsigned char *shiftArray4Bits( unsigned char *srcArray ) {
int srcLen = strlen(srcArray);
unsigned char temp = 0;
unsigned char *destArray;
destArray = malloc(srcLen + 1);
if(destArray == NULL) {
return NULL; // Failed to allocate memory
}
for(int i = 0; i < srcLen; i++) {
dest[i] = temp | ((srcArray[i] & 0xF0) >> 4);
temp = (srcArray[i] & 0x0F) << 4;
}
dest[i] = temp;
return dest;
}