在C语言中,从字节数组中一次读取两个字节

在C语言中,从字节数组中一次读取两个字节,c,arrays,memory,C,Arrays,Memory,假设我有以下字节数组: uint8_t barr[4] = {0xCE, 0xCE, 0xCE, 0xCE}; 给定索引n,我希望能够读取两个字节: uint16_t d16 = barr[0]; 并使d16等于 0xCECE 也许标准库中有一个函数可以执行这样的任务?小菜一碟: memcpy(&d16, barr + n, sizeof(d16)); 不要试图转换指针或使用unions。这些行为要么是未定义的行为,要么可能会绊倒陷阱表示 MycPyI[])/CODE >是“规

假设我有以下字节数组:

uint8_t barr[4] = {0xCE, 0xCE, 0xCE, 0xCE};
给定索引
n
,我希望能够读取两个字节:

uint16_t d16 = barr[0];
并使
d16
等于

0xCECE
也许标准库中有一个函数可以执行这样的任务?

小菜一碟:

memcpy(&d16, barr + n, sizeof(d16));


不要试图转换指针或使用
union
s。这些行为要么是未定义的行为,要么可能会绊倒陷阱表示<代码> MycPyI[])/CODE >是“规范”的解决方案(如C++ Boost库所做的)。

< P>一个线性的和迂回的安全方法:

#include <stdint.h>
#include <stdio.h>
#include <arpa/inet.h> /* for ntohs() */

union Convert
{
  uint16_t  to_integer_big_endian;
  uint8_t barr[sizeof (uint16_t)];
};

uint16_t pick_and_convert(uint8_t * barr, size_t s, size_t n)
{
  union Convert c = {0};  /* Take out-of-bound bytes as 0s. */

  for (size_t i = 0; i < sizeof c.barr && (n + i) < s; ++i)
  {
    c.barr[i] = barr[n + i];
  }

  return ntohs(c.to_integer_big_endian);
}

int main(void)
{
   uint8_t barr[4] = {1, 2, 3, 4}; /* Assuming a binary sequence. */
   size_t n;

   scanf("%zu", &n);

   uint16_t to_integer = pick_and_convert(barr, sizeof barr / sizeof *barr, n);

   printf("result = 0x%hx\n", to_integer);
 }
#包括
#包括
#包括/*用于ntohs()*/
联合皈依者
{
uint16到整数或大整数;
uint8_t barr[sizeof(uint16_t)];
};
uint16拾取和转换(uint8*barr、大小s、大小n)
{
union Convert c={0};/*将绑定的字节取为0*/
对于(尺寸i=0;i
总而言之,这是一个简单而充分的答案。@JanParzydło不那么容易,也许你应该读一下endianess。考虑不同值{0x11,0x12,0x13,0x14}的示例,为什么在C?@ @ ALK时升压为参考。这是C和C++之间的相同情况。@ ALK很好。所有示例值都相同。是否应将
0x01、0x02
作为
0x0102
0x0201
配对?您知道数据和您自己系统的终结性吗?终结性保存还是终结性安全?