当前位置: 首页 > 知识库问答 >
问题:

将uint8_t[4]转换为uint32_t并在C中返回

景恩
2023-03-14

我编写此测试是为了将uint8[4]转换为uint32_?我假设可以通过位移位以相同的方式完成,但我不确定如何。。。

uint32_t u32(uint8_t b[4]){
  uint32_t u;
  u = b[0];
  u = (u  << 8) + b[1];
  u = (u  << 8) + b[2];
  u = (u  << 8) + b[3];
  return u;
}

void p(uint32_t value){
        printf("\nuint32: %u\n",value);
}

int main(){
 uint8_t b[4];
 char a[4] = "test";
 char tmp[32];

 int i;
 for(i=0;i<4;i++){
   b[i] = a[i];
   sprintf(tmp,"%s%u",tmp,b[i]);
 }

 printf("uint8: ");

 for(i=0;i<4;i++)
   printf("%u",b[i]);

uint32_t t2 = u32(b);
 p(t2);
 return 0;
}

共有3个答案

王宜
2023-03-14

另一种可能的解决方案,具有最少的计算资源需求,无需可怕的铸造,并且非常便携。

uint32_t v = 0x11223344;

union ui32_to_ui8 {
    uint32_t ui32;
    uint8_t ui8[4];
};

ui32_to_ui8 u;

// ----- uint32_t => uint8_t array ------------------------
u.ui32 = v;

// you can read off like this
for (unsigned idx = 0; idx < 3; ++idx) {
    b[idx] = u.ui8[idx];  // tx each byte
}

// OR you can do this
b[0] = u.ui8[0];
b[1] = u.ui8[1];
b[2] = u.ui8[2];
b[3] = u.ui8[3];

// ----- uint8_t array => uint32_t ------------------------
for (unsigned idx = 0; idx < 3; ++idx) {
    u.ui8[idx] = b[idx];
}

v = u.ui32;  // read out the 32 bit value.
彭鸿畅
2023-03-14

您的u32()函数是主机端不可知代码读取大端数的一个很好的练习
它当然可以很容易地反转,只需从函数的末尾开始,然后转到函数的开头,分解uint32_t

void u8from32 (uint8_t b[4], uint32_t u32)
    b[3] = (uint8_t)u32;
    b[2] = (uint8_t)(u32>>=8);
    b[1] = (uint8_t)(u32>>=8);
    b[0] = (uint8_t)(u32>>=8);
}
于正志
2023-03-14

我尝试做一些不同的事情,使用已知的函数,而不是自己实现的。我的主要观点是告诉你字节存在于内存中,你对它们的解释取决于上下文。注意,有一些endpoint问题需要注意。此外,最好的经验是使用逐位运算。

#include <stdint.h>
#include <stdio.h>
#include <arpa/inet.h>
int main()
{
        uint8_t a[4]={0x1,0x2,0x3,0x4};
        uint32_t b = *((uint32_t*) a);
        /* turning an array to unit32 */
        printf("0x%x\n",htonl(b));
        /* turn an uint32 to array */
        uint32_t c = htonl(b);
        uint8_t d[4] = {0};
        printf("0x%x\n",c);
        for (int i=0; i<4 ;++i)
                d[i] = ((uint8_t*)&c)[3-i];
        for (int i=0; i<4 ;++i)
                printf("0x%x\n",d[i]);
        return 0;
}

输出为:

0x1020304
0x1020304
0x1
0x2
0x3
0x4

拆解它[您可以使用lldb或gdb加载程序]:

root# otool -tv a.out
a.out:
(__TEXT,__text) section
_main:
0000000100000e50    pushq   %rbp
0000000100000e51    movq    %rsp, %rbp
0000000100000e54    subq    $0x30, %rsp
0000000100000e58    movl    $0x0, 0xfffffffffffffffc(%rbp)
0000000100000e5f    movl    0x12b(%rip), %eax
0000000100000e65    movl    %eax, 0xfffffffffffffff8(%rbp)
0000000100000e68    movl    0xfffffffffffffff8(%rbp), %eax
0000000100000e6b    movl    %eax, 0xfffffffffffffff4(%rbp)
0000000100000e6e    movl    0xfffffffffffffff4(%rbp), %edi
0000000100000e71    callq   0x100000f50
0000000100000e76    leaq    0x117(%rip), %rdi
0000000100000e7d    movl    %eax, %esi
0000000100000e7f    movb    $0x0, %al
0000000100000e81    callq   0x100000f66
0000000100000e86    movl    0xfffffffffffffff4(%rbp), %edi
0000000100000e89    movl    %eax, 0xffffffffffffffe0(%rbp)
0000000100000e8c    callq   0x100000f50
0000000100000e91    movl    $0x0, %esi
0000000100000e96    movabsq $0x4, %rdx
0000000100000ea0    leaq    0xffffffffffffffec(%rbp), %rcx
0000000100000ea4    movl    %eax, 0xfffffffffffffff0(%rbp)
0000000100000ea7    movq    %rcx, %rdi
0000000100000eaa    callq   0x100000f60
0000000100000eaf    leaq    0xde(%rip), %rdi
0000000100000eb6    movl    0xfffffffffffffff0(%rbp), %esi
0000000100000eb9    movb    $0x0, %al
0000000100000ebb    callq   0x100000f66
0000000100000ec0    movl    $0x0, 0xffffffffffffffe8(%rbp)
0000000100000ec7    movl    %eax, 0xffffffffffffffdc(%rbp)
0000000100000eca    cmpl    $0x4, 0xffffffffffffffe8(%rbp)
0000000100000ed1    jge 0x100000efe
0000000100000ed7    movl    $0x3, %eax
0000000100000edc    subl    0xffffffffffffffe8(%rbp), %eax
0000000100000edf    movslq  %eax, %rcx
0000000100000ee2    movb    0xfffffffffffffff0(%rbp,%rcx), %dl
0000000100000ee6    movslq  0xffffffffffffffe8(%rbp), %rcx
0000000100000eea    movb    %dl, 0xffffffffffffffec(%rbp,%rcx)
0000000100000eee    movl    0xffffffffffffffe8(%rbp), %eax
0000000100000ef1    addl    $0x1, %eax
0000000100000ef6    movl    %eax, 0xffffffffffffffe8(%rbp)
0000000100000ef9    jmpq    0x100000eca
0000000100000efe    movl    $0x0, 0xffffffffffffffe4(%rbp)
0000000100000f05    cmpl    $0x4, 0xffffffffffffffe4(%rbp)
0000000100000f0c    jge 0x100000f3c
0000000100000f12    leaq    0x7b(%rip), %rdi
0000000100000f19    movslq  0xffffffffffffffe4(%rbp), %rax
0000000100000f1d    movzbl  0xffffffffffffffec(%rbp,%rax), %esi
0000000100000f22    movb    $0x0, %al
0000000100000f24    callq   0x100000f66
0000000100000f29    movl    %eax, 0xffffffffffffffd8(%rbp)
0000000100000f2c    movl    0xffffffffffffffe4(%rbp), %eax
0000000100000f2f    addl    $0x1, %eax
0000000100000f34    movl    %eax, 0xffffffffffffffe4(%rbp)
0000000100000f37    jmpq    0x100000f05
0000000100000f3c    movl    $0x0, %eax
0000000100000f41    addq    $0x30, %rsp
0000000100000f45    popq    %rbp
0000000100000f46    ret
0000000100000f47    nopw    (%rax,%rax)
__OSSwapInt32:
0000000100000f50    pushq   %rbp
0000000100000f51    movq    %rsp, %rbp
0000000100000f54    movl    %edi, 0xfffffffffffffffc(%rbp)
0000000100000f57    movl    0xfffffffffffffffc(%rbp), %edi
0000000100000f5a    bswapl  %edi
0000000100000f5c    movl    %edi, %eax
0000000100000f5e    popq    %rbp
0000000100000f5f    ret
 类似资料:
  • uint8_t, uint16_t, uint32_t, uint64_t 是什么数据类型? 那么_t的意思到底表示什么?它就是一个结构的标注,可以理解为type/typedef的缩写,表示它是通过typedef定义的,而不是其它数据类型。 uint8_t,uint16_t,uint32_t 等都不是什么新的数据类型,它们只是使用typedef给类型起的别名,新瓶装老酒的把戏。不过,不要小看了ty

  • 我目前正在进行一个需要使用uint8_ t的项目。我发现了一个问题,有人能解释一下为什么会发生这种情况吗? 在这种情况下,输出是预期的 但是当我取消注释第一行并使用uint8_ t时,输出是 这种行为给我带来了麻烦。 谢谢你的帮助。 马雷克

  • 问题内容: 怎么转换成?如果应该这样做 那怎么算呢? 以及如何转换为? 问题答案: 缓冲区长度为frameCapacity * bytesPerFrame。以下是可以在NSData和AVAudioPCMBuffer之间进行转换的函数。

  • 我希望代码得到一个int作为参数,如果年龄是奇数,则加3,如果是偶数,则加2,然后作为字符串返回。 有了这个代码我得到了 不兼容的类型:无法将int转换为字符串 九号线不是已经换了吗?

  • 我正在开发一个使用C/C++代码的Android库。 我显然有某种编码错误,只在运行时出错。 错误: 如果我正确理解,那么我应该能够将返回值强制转换为,然后能够将其分配给我的一个java类中的。然而,事实并非如此。 您将注意到,可以将强制转换为,因为我将其作为参数传入。通过执行c代码,我可以确认这是真的。 将转换/强制转换为的正确方法是什么?

  • 假设我有2个无符号数字,每个32位,保存在一个数组中。第一个数字包含在位置 [0; 3] 中,第二个数字包含在位置 [4; 8] 中。我现在要更改其中一个数字的值,以下代码是否允许/有问题?