有符号位与无符号位超超超详解!!!

文章详细介绍了有符号位和无符号位的概念,包括它们在内存中的存储方式(使用补码)、取值范围以及不同类型的转换。通过举例说明了在C语言中char、short、int、long等类型的有符号和无符号版本的赋值过程,特别是当数值超出类型范围时的行为。文章强调了补码的重要性,因为它允许统一处理符号位和数值位,简化了加减运算。
摘要由CSDN通过智能技术生成

有符号位与无符号位有哪些

1.首先了解有符号位和无符号位有哪些

:
char
unsigned char(无符号位char)(补充一下char也是整形,因为char内本质存的是ASCII)
signed char(符号位char)
short
unsigned short [int] (无符号位short)
signed short [int] (符号位short)
int
unsigned int(无符号位int)
signed int(符号位int)
long
unsigned long [int] (无符号位long)
signed long [int] (符号位long)

注:signed char,signed short,signed int,signed long就是char,short,int,long

关于符号位的定义

有符号位是将二进制中最高位看成符号位,其余为数值位
无符号位是将二进制中都看成数值位

各类型的范围

#include <limits.h>
int main() {
	INT_MAX;
}

在这里插入图片描述
这里就要用到limits.h这个头文件了,右击INT_MAX转到定义就能看见取值范围
在这里插入图片描述
这里我们以char类型为例:
有符号位char的取值范围就是-128到127
无符号位char的取值范围就是0到0xff(十进制是255)
其他的类型可以自行观察
在这里插入图片描述

signed short 2个字节
取值范围:-32768~32767
unsigned short 2个字节
取值范围:0~65535
signed int 4个字节
取值范围:-2147483648~2147483647
unsigned int 4个字节
取值范围:0~4294967295
signed long 4字节
取值范围: -2^31 ~ 2^31-1
unsigned long 4字节
取值范围:4 0 ~ 2^32

赋值的过程

首先要了解存入内存的都是补码,那为什么要存补码呢?

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路

下面用一个例子直观的解释
用原码1+(-1)得到的是-2,可以看出用原码计算有时会出错(因为原码不能将符号位和数值域统一处理)
在这里插入图片描述

然后了解原码反码补码如何相互转化

大家也可以看我另一篇博客操作符详解里面有介绍什么是原码反码补码

整数的2进制表示也有三种表示形式:
正的整数,原码、反码、补码相同
负的整数,原码、反码、补码是需要计算的
原码:直接通过正负的形 式写出的二进制序列就是原码-1
反码:原码的符号位不变,其他位按位取反得到的就是反码
补码: 反码+1就是补码
/整数内存中存放是补码的二进制序列

开始上例子

有符号位char赋值的轮回
有符号位char赋值的轮回
无符号位char赋值的轮回
在这里插入图片描述

/输出什么?
#include <stdio.h>
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
//-1不在unsigned char的范围内
//算出-1的
//原码10000000000000000000000000000001
//反码11111111111111111111111111111110
//补码11111111111111111111111111111101
//截取后存储在c中的为11111111又因为c把最高位也看出数值位所以是255
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}

在这里插入图片描述

2.
#include <stdio.h>
int main()
{
char a = -128;
//-128的补码10000000
//整形提升是按照类型自己的类型来看是否将最高位看成符号位这里是char
//所以整形提升后补码是11111111111111111111111110000000
//然后%u将a看成无符号位所以原码反码补码都一样
printf("%u\n",a);
return 0;
}

在这里插入图片描述

3.
#include <stdio.h>
int main()
{
char a = 128;
//这里大家可能就蒙了怎么会输出的和上面一样呢
//因为128截断后存入c中也是10000000
//所以整形提升后补码是11111111111111111111111110000000
//然后%u将a看成无符号位所以原码反码补码都一样
printf("%u\n",a);
return 0;
}

在这里插入图片描述

#include <windows.h>
int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)
	{
	当i=-1时存的是11111111111111111111111111111111
		printf("%u\n", i);
		//睡眠1000ms
		Sleep(1000);
	}
	system("pause");
}

在这里插入图片描述

7.
#include <stdio.h>
unsigned char i = 0;
int main()
{
for(i = 0;i<=255;i++)
{
//这就是一个轮回的案例当i为255时+1就是0所以是个死循环
printf("hello world\n");
}
return 0;
}

在这里插入图片描述

#include <stdio.h>
unsigned char i = 0;
int main()
{

	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
	//这也是个轮回的,char范围在-128到127只有255个数
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
	system("pause");
}

在这里插入图片描述

总结

有符号位char被赋值,先将右边的数转成补码截断后8bit位输出时,先将最高位看成符号位整形提升为补码,然后看输出的是%d还是%u,%d就是将补码转化成原码输出,%u就是将char看成存储的是无符号位,补码就是原码
无符号位char被赋值,先将右边的数转成补码截断后8bit位输出时,先将最高位看成数值位高位补0提升为补码,然后看输出的是%d还是%u,%d就是将补码转化成原码输出,%u就是将char看成存储的是无符号位,补码就是原码
有符号位int,是将右边赋值的补码的做高位看成符号位存入,输出时如果是%u将最高位看成数值位,如果是%d将最高位看成符号位
无符号位int,是将右边赋值的补码的最高位看成数值位存入,输出时如果是%u将最高位看成数值位,如果是%d将最高位看成符号位
然后个人理解就是被赋值时是在范围内进行轮回,也就解释了128和-128存在char中补码相同因为128是127+1而127加一在char范围中的轮回就是-128,int类型同样适用这个观点

大家有什么问题都可以在评论区提问,我看见就会回,希望大家留下宝贵的建议,别忘记一键三连!!!!也可以看看我的主页ltzoro博主
更多系列传送门:
小白初始c语言
剖析函数栈帧的创建与销毁
新手专用练手项目–三子棋
小白的第二个项目–扫雷游戏
操作符详解
C语言初识指针
在这里插入图片描述

  • 42
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 28
    评论
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zoro-1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值