Typecasting指针改变其大小(以字节为单位)

时间:2015-04-03 23:31:40

标签: c pointers casting uint8t

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

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

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')”和“警告:从指针转换为不同大小的整数”。

我做错了什么?

1 个答案:

答案 0 :(得分: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'代表big-endian,也就是说,数据以网络字节顺序存储,首先是最重要的字节。