Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 将3字节数组强制转换为int32_Arrays_C_Integer - Fatal编程技术网

Arrays 将3字节数组强制转换为int32

Arrays 将3字节数组强制转换为int32,arrays,c,integer,Arrays,C,Integer,快速提问, 我想将一个3字节有符号2的补码数组转换成一个小的endian int32我尝试将memcpy的大小设置为3,并将目标地址设置为+1(而不会忘记将我的int32初始化为零) 这是我的密码: int main(void) { // little endian 3 bytes __uint8_t n1[]={0,0xFF,0xDE,0x81}; __uint8_t n2[]={0xFF,0xDE,0x81}; // temp var __int32_t tmp1

快速提问,
我想将一个3字节有符号2的补码数组转换成一个小的endian int32
我尝试将memcpy的大小设置为3,并将目标地址设置为+1(而不会忘记将我的int32初始化为零)
这是我的密码:

int main(void) 
{
  // little endian 3 bytes
  __uint8_t n1[]={0,0xFF,0xDE,0x81};
  __uint8_t n2[]={0xFF,0xDE,0x81};
  
  // temp var
  __int32_t tmp1=0;
  __int32_t tmp2=0;
  
  // cast array to int
  memcpy(&tmp1,n1,4);
  memcpy((&tmp2)+1,n2,3);
  
  // printf
  printf("n1 : %d\n",tmp1);
  printf("n2 : %d\n",tmp2);
}
我得到的输出:

n1 : -2122195201
n2 : 0
我想要的输出:

n1 : -2122195201
n2 : -2122195201
我该如何解决这个问题?也许使用union更好?

通过执行
(&tmp2)+1
可以获取
tmp2
的地址,它是指向
int32\t
的指针,并递增该指针。所以你给它的地址加上4。这意味着memcpy的目标地址是
tmp2
+4的地址。实际上,您没有修改
tmp2
,而是重叠了一些其他变量或内存

这不是一种转换或强制转换数据的干净方法,但如果您真的想使用memcpy,请执行类似(未测试)
memcpy((void*)((char*)&tmp2)+1)、n2,3的操作

通过执行
(&tmp2)+1
获取
tmp2
的地址,它是指向
int32\t
的指针,并递增该指针。所以你给它的地址加上4。这意味着memcpy的目标地址是
tmp2
+4的地址。实际上,您没有修改
tmp2
,而是重叠了一些其他变量或内存


这不是一种转换或强制转换数据的干净方法,但如果您真的想使用memcpy,请执行类似(未测试)
memcpy((void*)((char*)&tmp2)+1)、n2,3的操作

我会避免强制转换值,并使转换显式(这可能是内联的)

我假设你的角色数组也是小endian。(否则交换索引)


static int three2four(\uu uint8\u t three[3])
{
int-val;

val=((unsigned)three[2]我将避免强制转换该值,并使转换显式(这可能是内联的)

我假设你的字符数组也是小端的(否则交换索引)


static int three2four(\uu uint8\u t three[3])
{
int-val;

val=((无符号)三[2]
(&tmp2)
指向名为
tmp2
(&tmp2)的
+1
指向下一个
\uuuuu int32\u t
的位置,因为指针算术以指向类型为单位进行操作。要指向
\uuuu int32\u t
的第一个字节,请转换指针,就像
(char*)&tmp2
一样。然后,要指向下一个字节,请使用
((char*)&tmp2)+1
。这就是说,像这样将三个字节复制到32位
int
中是非常不寻常的。它通常不是好程序的一部分。
(&tmp2)
指向名为
tmp2
(&tmp2)的
+1
指向下一个
\uuuuu int32\u t
的位置,因为指针算术以指向类型为单位进行操作。要指向
\uuuu int32\u t
的第一个字节,请转换指针,就像
(char*)&tmp2
一样。然后,要指向下一个字节,请使用
((char*)&tmp2)+1
。也就是说,像这样将三个字节复制到32位的
int
中是非常不寻常的。这通常不是一个好程序的一部分。谢谢,它可以工作,我以前总是使用字节,所以我忘了这个^^谢谢,它可以工作,我以前总是使用字节,所以我忘了这个^^
static int three2four(__uint8_t three[3] )
{
int val;
val = ((unsigned)three[2] << 16) | ((unsigned)three[1] << 8) | (unsigned)three[0] ;
if (three[2] & 0x80) val |= (0xffu << 24);

return val;
}