我在这里遇到了问题。我输入一个整数,输入整数指针并将其发送到函数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*
的一个正在使输出出错。或者我错过了什么?
答案 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,因此符号扩展首先在。 (它还需要将浮动的推广加倍)。