目录
1.原码、反码、补码
一个数的二进制有3种形式:原码、反码、补码。
📕原码就是一个数的正常二进制有符号数最高位为符号位(0为正数,1为负数)
例:
8的原码(默认为int类型,4字节32个bit位)
8的原码为: 0000 0000 0000 0000 0000 0000 0000 1000
-8的原码为: 1000 0000 0000 0000 0000 0000 0000 1000
📗反码是符号位不变,其他位按位取反。
例:
8的反码为: 0111 1111 1111 1111 1111 1111 1111 0111
-8的反码为: 1111 1111 1111 1111 1111 1111 1111 0111
📘补码是在反码的基础上在最低为加1。
例:
8的补码为: 0111 1111 1111 1111 1111 1111 1111 1000
-8的补码为: 1111 1111 1111 1111 1111 1111 1111 1000
计算机中数值一律用补码的形式存储和表示!!o(* ̄▽ ̄*)o
2.整形提升
C的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升!
整型提升的意义:
表达式的整型运算要在CPU的相应运算器件内执行(只有加法器),CPU内整型运算器的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
通用CPU难以实现两个8bit字节直接相加运算。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
因此,及时两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。补为整型长度时规则为:有符号数补符号位,无符号数补0。
例:
int main()
{
char a=-1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
}
输出-1 -1 255
-1的原码:10000000 00000000 00000000 00000001
-1的反码:11111111 11111111 11111111 11111110
-1的补码:11111111 11111111 11111111 11111111
char类型只取补码的8位: 11111111
整形提升(高位补):无符号位补0,有符号位补符号位
a:11111111 11111111 11111111 11111111
(负数)转化为原码为-1:
10000000 00000000 00000000 00000001
b: 11111111 11111111 11111111 11111111
(负数)转化为原码为-1:
10000000 00000000 00000000 00000001
c:00000000 00000000 00000000 11111111
(正数)转化为原码为255:
00000000 00000000 00000000 11111111
这里虽然我定义abc是字符类型,但是我打印的时候用%d的形式进行打印,及用整型类型打印,所以要进行整型提升。
再来一个例题:先自己做做哟!!!!
例题(取值范围):
int main()
{
unsigned char a=200;
unsigned char b=100;
unsigned char c=0;
c=a+b;
printf("%d %d",a+b,c);
return 0;
}
铛铛铛!!!!!公布答案:
200的补码:
0000 0000 0000 0000 0000 0000 1100 1000
a为unsigned char类型取8bit:1100 1000
100的补码:
0000 0000 0000 0000 0000 0000 0110 0100
b为unsigned char类型取8bit:0110 0100
c=a+b的补码:
10010 1100取8位为:0010 1100(高位丢失)再整型打印高位补0及十进制44
而a+b整型打印有32bit位高位没有丢失,打印为300
3.大小端字节序存储
大小端字节序是指数据在电脑上存储的字节顺序。
大端:低字节内容放高地址,高字节内容放低地址。
小端:低字节内容放低地址,高字节内容放高地址。
如下图visual studio2019中就是小端字节存储。55低字节放到了低地址处。
这里说下如何在visual studio 2019编译器中如何查看内存
在该数代码打断点,然后开始调试点击 菜单栏中的调试->窗口->内存。运行过断点处代码输入&num及地址即可查看。
那么可能有的人还是不相信,在这里我用代码简单的验证下visual studio编译器是大端字节序还是小端字节序。
代码如下:
#include<stdio.h>
int test()
{
int num = 1;
return *(char*)#
//1的补码为00000000 00000000 00000000 00000001
//char*指针 只能访问1个字节即00000001再对该指针解引用即为1.
}
int main()
{
int ret = test();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
各位老铁们,今天的分享就到这里,感谢大家的支持!!!!