Я бы сказал, что memcpy
не способ сделать это.Однако, поиск best сильно зависит от того, как ваши данные хранятся в памяти.
Начнем с того, что вы не хотите брать адрес переменной назначения.Если это локальная переменная, вы принудительно поместите ее в стек, а не дадите компилятору возможность поместить ее в регистр процессора.Это само по себе может быть очень дорогим.
Самое общее решение - прочитать данные побайтно и арифметически объединить результат.Например:
uint16_t res = ( (((uint16_t)char_array[high]) << 8)
| char_array[low]);
Выражение в 32-битном случае немного сложнее, поскольку у вас есть больше альтернатив.Возможно, вы захотите проверить вывод ассемблера, который лучше.
Alt 1: построить Париж и объединить их:
uint16_t low16 = ... as example above ...;
uint16_t high16 = ... as example above ...;
uint32_t res = ( (((uint32_t)high16) << 16)
| low16);
Alt 2: сдвиг в 8 битов за раз:
uint32_t res = char_array[i0];
res = (res << 8) | char_array[i1];
res = (res << 8) | char_array[i2];
res = (res << 8) | char_array[i3];
Все приведенные выше примеры нейтральны по отношению к порядку байтов используемого процессора, так как значения индекса определяют, какую часть читать.
Возможен следующий вид решений, если 1) порядок байтов (порядок байтов)) устройства соответствуют порядку, в котором байты хранятся в массиве, и 2) массив, как известно, размещается по выровненному адресу памяти.Последний случай зависит от машины, но вы в безопасности, если массив char, представляющий 16-битный массив, начинается с четного адреса, а в 32-битном случае он должен начинаться с адреса, делимого на четыре.В этом случае вы можете просто прочитать адрес после некоторых уловок указателя:
uint16_t res = *(uint16_t *)&char_array[xxx];
Где xxx
- индекс массива, соответствующий первому байту в памяти.Обратите внимание, что это может не совпадать с индексом наименьшего значения.
Я бы настоятельно рекомендовал первый класс решений, поскольку он не зависит от порядка байтов.
В любом случае, оба онинамного быстрее, чем ваше memcpy
решение.