Я пытаюсь записать 16 значений без знака в 8 байтов (64 бит) и получить к ним доступ с использованием синтаксиса типа массива.
Каждая запись в массиве будет одним полубайтом - длиной 4 бит. (Значения, которые я планирую хранить, никогда не больше 15).C: Реализация массива nibbles
Моя первая попытка была такова:
int main(int argc, char* argv[]) {
union nibbles_array {
uint64_t as_long;
struct inner_array {
unsigned entry0 : 4;
unsigned entry1 : 4;
unsigned entry2 : 4;
unsigned entry3 : 4;
unsigned entry4 : 4;
unsigned entry5 : 4;
unsigned entry6 : 4;
unsigned entry7 : 4;
unsigned entry8 : 4;
unsigned entry9 : 4;
unsigned entry10 : 4;
unsigned entry11 : 4;
unsigned entry12 : 4;
unsigned entry13 : 4;
unsigned entry14 : 4;
unsigned entry15 : 4;
} as_array;
} array;
array.as_long = 0xabcdef;
printf("%d \n", array.as_array.entry0);
printf("%d \n", array.as_array.entry1);
printf("%d \n", array.as_array.entry2);
printf("%d \n", array.as_array.entry3);
printf("%d \n", array.as_array.entry4);
return 0;
}
Две проблемы проистекают из этой реализации: первая в том, что значения сохраняются в обратном порядке. Я могу, конечно, назначить значения в обратном порядке, чтобы получить желаемый результат: array.as_long = 0xfedcba
, но я хочу, чтобы этот код был портативным, а не зависящим от него. Во-вторых, я не могу получить доступ к nibbles с индексом в синтаксисе типа массива.
Вторая попытка была такова:
int main(int argc, char* argv[]) {
uint64_t pseudo_array = 0xabcdef;
#define Array(i) (unsigned)((pseudo_array & (0xfUL << i)) >> i)
int i;
for (i = 0; i < 16; ++i) {
printf("%d ", Array(i));
}
printf("\n");
return 0;
}
выше может решить вторую задачу (массив-подобный синтаксис); Теперь я могу получить доступ к «элементов» с индексом, но проблема остается порядок байтов, плюс это дает неправильный вывод:
15 7 11 13 14 15 7 11 13 6 3 9 12 14 15 7
- Почему выше производит этот выход?
- Можете ли вы предложить реализацию, которая позволит мне получить доступ к «массиву» по индексу , а решит проблему с энтианностью?
Что заставляет вас думать, что ваша вторая попытка все еще имеет проблему с энтианностью? –
Вам нужно умножить 'i' на 4 при использовании его в качестве величины сдвига смешения (суммы сдвига в битах). Кроме того, вы можете устранить сдвиг, просто перенесив 'pseudo_array' справа на' 4 * i', затем замаскируйте (вы можете даже сделать перед маскировкой). –
Пожалуйста, покажите определение 'uint64_t'. – Codor