整数的二进制表示有三种:原码,反码,补码
有符号的整数,三种表示方法均有符号位和数值位两部分,符号位都是用‘0’表示“正,用1表示‘负’
最高位的以为被当作符号位,剩余的都是数值位。
整数的原码,反码,补码都相同
负整数的三种表示方法各不相同
原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码
反码:将原码的符号位不变,其他位一次按位取反就可以得到反码
补码:反码+1就是补码
对于整形来说:数据存放内存中起始存放的就是二进制的补码
为什么呢?
在计算机系统中,数值一律用补码来表示和存储
原因在于,使用补码,可以将符号位和数值与统一处理
同时,加法和减法也可以统一处理(CPU只有加法器),此外补码和原码可以相互转换,其运算过程是相同的,不需要额外的硬件电路
例题:变量不同的定义,分别用整形进行打印
#include<stdio.h>
int main()
{char a = -1;signed char b = -1;unsigned char c = -1;printf("a=%d,b=%d,c=%d",a,b,c);return 0;}
运行结果是:a=-1,b=-1,c=255
这是因为
//-1是一个负数 //原码:10000000000000000000000000000001//反码:11111111111111111111111111111110//补码:11111111111111111111111111111111//所以char占用8个bit,截断所以a-11111111//反码:10000000000000000000000000000000 //原码:10000000000000000000000000000001 //%d打印有符号的整数,要看符号位 //%u打印无符号的整数,不用看符号位 //而char类型大部分编译器是默认为有符号的//所以a和b都是运行出来都是-1, //在c里面a->11111111//整型提升:无符号整数,高位补0//提升:00000000000000000000000011111111 符号位是0代表正数。//原码,反码,补码相同,所以c就是255
例题:运行结果是4294967168
#include<stdio.h>
int main()
{char a = -128;printf("%u",a);return 0;} //-128的原码//原码:10000000000000000000000010000000 //反码:11111111111111111111111101111111//补码;11111111111111111111111110000000 //char占8个bit,截断8位//a——10000000 //整形提升,高位时1,有符号位,高位补符号位 //提升:11111111111111111111111110000000//他其实就是在内存中是补码 //%u打印无符号整数,%u的角度,他认为内存中存储的是无符号的整数。//所以认位他没有符号位//直接打印:11111111111111111111111110000000
例题:有符号整数和无符号整数分别进行打印
#include<stdio.h>
int main()
{signed int num = -10; printf("%d\n",num); //-10printf("%u\n",num); //4294967286return 0;}
#include<stdio.h>
int main()
{unsigned int num = -10; printf("%d\n",num); //-10printf("%u\n",num); //4294967286return 0;}
所以对于按照不同方式打印的,就是要根据他的类型进行判断,是unsigned就用%u打印,是signed就用%d进行打印。
例题:
#include<stdio.h>
#include<string.h>
int main()
{char a[1000];int i=0;for(i=0;i<1000;i++){a[i]=-1 - i;}printf("%d",strlen(a));return 0;} //运行结果:255//strlen是求的字符串的长度,统计的是\0之前出现的字符的个数
就是从-1开始加加加,一直到-128 再加1就是127直到1,所以0之前的个数就是127+128=255,而不是1000.
例题:当无符号整数时全局变量的时候
#include<stdio.h>
unsigned char i = 0;//全局变量
int main()
{for(i=0;i<=255;i++){printf("hello world\n");}return 0;} //会一直循环,因为i是无符号字符型。
例题:
#include<stdio.h>
int main()
{unsigned char i ; for(i=9;i>=0;i--){printf("%u\n",i);}return 0;}
//会无限循环,unsigned是无符号整数,条件一直成立