0

我正在尝试使用指针在充满十六进制值的内存区域中移动。我使用 uint8_t 指针来确保它一次只指向 1 个字节。我想去一个特定的位置(从起始位置偏移字节数)并存储一组长度为 1、2、4 或 8 个字节的字节。然后,我想将该值解释并打印为有符号或无符号十进制(由枚举参数确定)。

我认为我可以简单地将指针从 1 字节 uint8_t 更改为字节数的正确大小(例如 uint64_t 用于 8 btyes),然后存储该值(因为我不能只打印一个字节有一次,我需要评估整个字节/字节组)。这是我到目前为止所拥有的:

void showValueAtOffset(FILE* Out, const uint8_t* const baseAddr, uint32_t Offset, Sign Sgn, uint8_t nBytes) {//------------------doesn't work----------------
   uint8_t *p = baseAddr;//create a pointer that points to the first byte of memory in the array
   for(int i = 0; i < Offset; i++){//use a for loop to move p to the location indicated by Offset 
       p++;
   }
   if(nBytes == 1){
       //pointer p already has the correct typecast for the number of bytes
       uint8_t N = *p;//store the value of the byte
       if(Sgn == SIGNED){
           int8_t result = N;
           fprintf(Out, "%d  ", result);//print the value
       }
       else{//if UNSIGNED
           fprintf(Out, "%u  ", N);//print the value
       }
   }
   else if(nBytes == 2){
       uint16_t q = (uint16_t) p;//create the pointer q with the correct typecast for the number of bytes
       uint16_t N = *q;//store the value of the bytes
       if(Sgn == SIGNED){
           int16_t result = N;
           fprintf(Out, "%d  ", result);//print the value
       }
       else{//if UNSIGNED
           fprintf(Out, "%u  ", N);//print the value
       }
   }
   else if(nBytes == 4){
       uint32_t q = (uint32_t) p;//create the pointer q with the correct typecast for the number of bytes
       uint32_t N = *q;//store the value of the bytes
       if(Sgn == SIGNED){
           int32_t result = N;
           fprintf(Out, "%d  ", result);//print the value
       }
       else{//if UNSIGNED
           fprintf(Out, "%u  ", N);//print the value
       }
   }
   else if(nBytes == 8){
       uint64_t q = (uint64_t) p;//create the pointer q with the correct typecast for the number of bytes
       uint64_t N = *q;//store the value of the bytes
       if(Sgn == SIGNED){
           signed int result = (signed int) N;
           fprintf(Out, "%d  ", result);//print the value
       }
       else{//if UNSIGNED
            unsigned int result = (unsigned int) N;
            fprintf(Out, "%u  ", result);//print the value
       }
   }
   else{
       //this should not happen according to the preconditions
   }
   fprintf(Out, "\n");
}

这不起作用,并且我收到几个错误,例如“无效类型论证'一元*'(具有'uint32_t')”和“警告:从指针转换为不同大小的整数”。

我究竟做错了什么?

4

1 回答 1

2

错误的直接来源是您应该使用uint16_t *q = (uint16_t *) p;,而不是uint16_t q = (uint16_t) p;,将指针类型类型转换为另一种指针类型,然后再解决它。

尽管如此,修改后的代码还是依赖于机器架构,存在大/小端和对齐的问题。简而言之,代码可以在 x86 机器上运行,但可能会由于未对齐的内存访问而崩溃,或者在其他架构上产生错误的数字。一种可移植的方式是这样的:

uint32_t to_uint32_be(const void* num)
{
    const uint8_t *p = num;
    uint32_t res = 0U;
    int i;
    for (i = 0; i < 4; i++)
        res = (res << 8) + p[i];
    return res;
}

在上面的代码中,“be”代表大端,即数据按网络字节顺序存储,最高有效字节在前。

于 2015-04-03T23:54:58.823 回答