目录
一.原码、反码、补码
二.大小端存储
三.通过调试来验证
四.整型提升
一.原码、反码、补码
#include<stdio.h>
int main()
{
int a = 1;
//00000000000000000000000000000001 - 原码
//正数的原码 反码 补码是相同的
//开头的第一个二进制位是符号位
//0为正,1为负
return 0;
}
a是int类型,占四个字节,一个字节8bit位,所以有整型变量a有32bit位
#include<stdio.h>
int main()
{
int a = -1;
//10000000000000000000000000000001 - 原码
//11111111111111111111111111111110 - 反码
//原码的符号位不动,其他位按位取反
//11111111111111111111111111111111 - 补码
//反码加一
//第一个是符号位
//0为正,1为负,所以是负数
return 0;
}
内存中存储的是补码
存补码的原因是为了方便计算
int main()
{
int a = 1 - 1;
//计算机只能算加法,如果我们按照原码来算
//00000000000000000000000000000001 - 1
//10000000000000000000000000000001 - -1
//10000000000000000000000000000010 - -2
//这样算得出的结果是-2,跟我们想要的结果不同
//但是按照反码来算
//00000000000000000000000000000001 - 1
//11111111111111111111111111111111 - -1
//100000000000000000000000000000000 - 0
//有33个bit位,而一个整型只有32个bit位
//所以默认取后面32bit位,结果就是0
return 0;
}
二.大小端存储
大端存储:数据的高位存储在地址的低位,数据的低位存储在地址的高位
小端存储:数据的高位存储在地址的高位,数据的低位存储在地址的低位
比如我们要存0x11223344这个数(0x表示这是个16进制数)
地址是由低到高排的,像这样数据的高位存储在地址的低位,数据的低位存储在地址的高位就是
大端存储
像这样数据的高位存储在地址的高位,数据的低位存储在地址的低位就叫小端存储
那么怎么来查看我们的电脑是大端存储还是小端存储呢
下面设计一个程序
& 取地址符
* 解引用操作符
#include<stdio.h>
int main()
{
int a = 1;
char* pa = (char*)&a;
//取a的地址是默认会是int*类型
//所以先强制类型转换为char*类型
//pa指向int四个字节中的第一个字节的地址
if (*pa == 1)//
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
1的大端存储为00 00 00 01
小端存储为01 00 00 00
那么*pa就是读取了int四个字节中的第一个字节
通过判断第一个字节是0还是1就可以判断是大端存储还是小端存储了
三.通过调试来验证
第一步,按下键盘上的F10/F11(Fn+F10/Fn+F11),开启调试
第二步
然后就会出现这样一个界面:
我们先要把“列:自动” 改成“列:4”方便我们的观察
我们先来看下当a=1时的情况:先点两下F10/F11,让a存储在内存中
再取a的地址
内存中存放的数据是以十六进制存储的
我们可以看到
中存放的是01 00 00 00
由于编译器采用的是小端存储,所以它实际上存储的数值是00 00 00 01
恢复成二进制就是00000000 00000000 00000000 00000001
就是1的补码
接下来看
a = -1时的情况
我们可以看到a的地址里存放的是ff ff ff ff转换为2进制就是补码,补码-1就是反码,反码取反是原码
补码:11111111 11111111 11111111
反码:11111111 11111111 11111110
原码:1000000 0000000 0000001
原码第一个2进制位是符号位,为1则为负
四.整型提升
int main()
{
char a = 1;
//把1这个常量赋值给a变量
// = 赋值运算符 从右往左操作
// 1 是int型的常量,有四个字节,而char类型只有一个字节
//00000000000000000000000000000001 - 1 补码(正数原码反码补码相同)
//00000001 - a 取后面八个bit位
return 0;
}
因为是小端存储,所以int的第一个字节给a,也就是后面8个bit位给了a
int main()
{
char a = 1;
printf("%d\n", a);
//char类型转换成int类型输出
//00000001
//根据符号位来补,如果符号位是0,就在前面补24个0
//如果符号位是1,就在前面补24个1
//00000000000000000000000000000001 补码(反码、原码)
char a = -1;
printf("%d\n", a);
//11111111
//11111111111111111111111111111111 - 补码 在内存中存储
//11111111111111111111111111111110 - 反码
//10000000000000000000000000000001 - 原码 输出
return 0;
}
希望有助于大家对整形存储的理解!
每个不曾起舞的日子
都是对生命的辜负。
——尼采