整数的二进制表示有三种:原码,反码,补码
有符号的整数,三种表示方法均有符号位和数值位两部分,符号位都是用‘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); //-10
printf("%u\n",num); //4294967286
return 0;
}
#include<stdio.h>
int main()
{
unsigned int num = -10;
printf("%d\n",num); //-10
printf("%u\n",num); //4294967286
return 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是无符号整数,条件一直成立
标签:存储,符号,int,补码,整数,char,内存,原码
From: https://blog.csdn.net/2401_83201682/article/details/143259374