标签:
1.编码:计算机底层的二进制数据0和1的组合,用来表示数据;
2.源码:计算机中有符号整数中的正数,以及无符号的整数,都用源码表示;
void main1()
{
int x = 2;//有符号的整型数据
unsigned y = 3;//无符号整型数据
//int类型的数据是有符号的,有符号的正数在计算机内存中用原码表示
//int类型的数据有四个字节,一个字节占八位,最高位表示符号,第一个数是0 代表正数,第一个数是1 代表负数
//x在计算机内存中的表示方法 0 000 0000, 0000 0000, 0000 0000, 0000 0000 表示数据的只有后面的31位二进制数
//y在计算机内存中的表示方法 0000 0000, 0000 0000, 0000 0000, 0000 0000 表示的数据的是32位二进制数据 y 是 unsigned类型的数据
printf("%x",&x);
/*原码有符号的前提下最高位为符号位,其余各位为数值本身的绝对值,无符号就是数据本身的绝对值 */
getchar();
}
计算机中的负数是用补码来表示的,
如何得出补码:源码取反得出反码,反码加一得出补码。(记得符号位不变,一直是1表示负数)
// 模拟 -1 在计算机内存中的存储
// 1 000 0000 0000 0000 0000 0000 0000 0001 -1的原码
// 1 111 1111 1111 1111 1111 1111 1111 1110 -1的反码,1变0, 0变1
// 1 111 1111 1111 1111 1111 1111 1111 1111 -1的补码(在反码的基础上加1)
/* 计算机系统中 ,数值一律用补码来表示 (正数与原码一样,可以理解为按照原码解析) 负数都是用补码 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 假设用八位来表示一个数 分别写出 +1 的原码, 反码, 补码 */
/* +1 原码 0000 0001 反码 0000 0001 补码 0000 0001 */
/* -1 原码 1 000 0001 反码 1 111 1110 补码 1 111 1111 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
关于原码补码的经典试题(据说世界五百强的都面试这题)
void mainA()
{
int x = -1;
printf("%x",&x);
printf("\n %d,%u",x,x); 结果是-1和4294967295
// %d按照有符号十进制打印,%u按照无符号十进制打印,
//printf函数就是直接抓取二进制数据,无论这个数据以前是什么类型,按照%d,%u的格式来解析
// f f f f f f f f
// 1 111 1111 1111 1111 1111 1111 1111 1111 -1的补码(在反码的基础上加1)
// 1 111 1111 1111 1111 1111 1111 1111 1110 -1的反码,1变0, 0变1
// 1 000 0000 0000 0000 0000 0000 0000 0001 -1的原码
//而%u按照无符号来解析,无符号没有符号位,所以打印出来的结果就是4294967295 (32个1的十进制)
getchar();
}
void mainB()
{
int x = 4294967295;
printf("%x",&x);//打印出来x的地址
printf("\n %d,%u",x,x);
//打印出来的结果与mainA的结果相反,原因也与他一样
getchar();
}
4294967295在内存中的储存格式是
11111111 11111111 11111111 11111111
按照十进制打印出来,读取最高位有1说明是负数,然后补码减1得反码:1 1111111 11111111 11111111 11111110
反码取反的原码:1 0000000 00000000 0000000 00000001 打印出来的结果就是-1
按照符号解析出来的结果就是一个正数 4296967295.
注意要分清原码、补码是如何转换的,原码存出什么数据,补码存出什么数据。
标签:
原文地址:http://www.cnblogs.com/ZHP-Study-share/p/5393493.html