使用char *和unsigned char打印整数的内存表示*

时间:2013-06-27 09:17:33

标签: c pointers memory-management char

我在这里遇到了问题。我输入一个整数,输入整数指针并将其发送到函数print_bytes,该函数接受char*指针和要打印的字节数。尝试打印每个字节的地址和十六进制类型的数字。但是对于250,o / p应该是第一个字节的fa和接下来的3个字节的零,而是为第一个字节输出fffffffa。

#include<stdio.h>
using namespace std;
void print_bytes(char* ptr,int len)
{
      for(int i=0;i<len;i++)
      {
             printf("%p  %x\n",ptr+i,*(ptr+i));         
      }     
}
int main()
{
      int a=250;
      print_bytes((char*)&a,4);
      return 0;
}

但是当我将指针类型更改为unsigned char*时,它会提供正确的输出。 这意味着MSB是char*的一个正在使输出出错。或者我错过了什么?

3 个答案:

答案 0 :(得分:0)

这是因为(在您的系统上)char已签名,并且已在int来电中升级为printf()

使用unsigned char

void print_bytes(const unsigned char *ptr, size_t len)
{
  for(size_t i = 0; i < len; ++i)
  {
    printf("%p  %x\n", ptr + i, ptr[i]);
  }
}

答案 1 :(得分:0)

printf("%p  %02x\n",ptr+i,(unsigned char)*(ptr+i));         

答案 2 :(得分:0)

传递给printf函数时,类型将被提升为signed int。当提升签名类型时,它是“符号扩展”。

对于8位签名的字符,值250相当于-6(2的补码),并且由于它是有符号的,因此-6被认为是“真”值。 当这被扩展为有符号整数(4个字节)时,正如此处所发生的那样,值-6被保留(通过符号扩展),而不是值250.但是4字节值上的-6是fffffffa,而它只是一个字节上的fa。

由于MSB充当了标志的标志,如果设置了标志,你就会得到你所观察到的行为。

在printf调用上转换为(unsigned char)将导致该值为“零扩展”。这将导致保留值250,而不是值-6,并将导致您想要的行为。

这是printf的要求(由标准设置),是一个可变函数(vararg),比int更窄的参数在被传递之前被提升为int,因此符号扩展首先在。 (它还需要将浮动的推广加倍)。