printf二进制原码反码补码

来源:百度知道 编辑:UC知道 时间:2024/05/22 08:11:12
原题目:
#include <stdio.h>
{char c;
c='\376';
printf("%d\n",c);
}
我自己分析了一下,其中有些不明白:
八进制数\376转为十进制数为254,ASCII值中的254用二进制表示为11 11 11 10,但它输出变成了-2.因此问题来了:
第一:是不是ASCII值中的254用二进制表示为11 11 11 10在计算机内存中是以二进制的补码表示的,然后 printf("%d\n",c);要以原码输出,反过来是-2是这样思路吗????
那其中又产生了一个问题,原码变补码是取反加1,那补码变原码 为减1取反,减1取反相当于取反加1吗?也就是:“补码变原码是取反加1”这句话对吗?
第二:如果不是这个思路,那应该怎么考虑呢,谢谢!

QQ280660936在线指导效果更好,谢谢

负数才以补码形式存放于内存中,补码变原码是再求一次补就好了

你的思路不完全正确,结果是取决于编译器的。当你用%d格式串输出字符型数据时需要对字符型数据进行扩展,内存中的数据就是11111110,但是不同的编译器对于这个数据的解释是不同的,有的编译器认为这是一个负数的补码(因为符号位是1),之后按你的思路把它翻译成-2(减1后取反)有的编译器会认为这是个正数,之后翻译成本来的254,你的编译器在进行扩展时恰好认为这是个负数,所以结果是-2。
相关的问题在C traps and pitfalls中有详细的说明。

%d是以整形输出,在C语言里整形是以补码的形式存储的。正数的补码是其本身,负数的补码是除符号位外取反加一。
求补码和补码求原码的过程是一样的,都是“取反加一”。