【C语言】整型的存储方式(大小端,原码,反码,补码)
创始人
2024-04-24 11:59:48
0

目录

一、基本类型

二、原码,反码,补码

2.1 原,反,补的计算方式

2.1.1 正数的原,反,补

2.1.2 负数的原,反,补

2.2 为什么要用补码存放

2.3 大小端是什么?

2.3.1 如何确定当前编译器是那种存储方式

2.4 signed(有符号),unsigned(无符号)

三、练习题

列1

列2

列3

END.


一、基本类型

char             //字符数据类型,用ascall码值存储

short            //短整型

int                //整形

long             //长整型

long long     //更长的整形

二、原码,反码,补码

2.1 原,反,补的计算方式

计算机是用二进制进行各种计算

原码,反码,补码是计算机进行存储数值的编码方式

原码:将数值直接转化为二进制

反码:第一位不变其余位全部取反(原来为1,取反为0)

补码:将反码+1

第一位是符号位,0表示正数,1表示负数

2.1.1 正数的原,反,补

具体怎样存储,举个简单的列子来说明:

int类型占用4个字节,1个字节(Byte)占用8个bit位(8个二进制位),需要32个二进制位才能放得下

正数的原码,反码,补码是相同的

原码:0000 0000 0000 0000 0000 0000 0000 1010(10为正数,最高位为符号位取0)

反码:0000 0000 0000 0000 0000 0000 0000 1010

补码:0000 0000 0000 0000 0000 0000 0000 1010

这里是用16进制进行表示,a表示10

2.1.2 负数的原,反,补

原码:1000 0000 0000 0000 0000 0000 0000 1010(-10为负数,最高位为符号位取1)

反码:1111 1111  1111  1111  1111  1111  1111  0101(符号位不变其余位取反)

补码:1111 1111  1111  1111  1111  1111  1111  0110(反码+1)

(8+4+2+1=15)

由此我们可以得知在计算机中存储时,实际上是存放的补码

2.2 为什么要用补码存放

计算机只会算加法,计算减法是用加一个负数来实现的(a+(-a))

当计算1+(-1)时

原码计算出的结果很显然不是我们所期望的

补码计算

 很显然补码计算的结果是正确的,所以采用补码

2.3 大小端是什么?

细心的同志可能已经有这样的疑问

为什么在计算机中存放数据是反着存放的?

这是因为在内存中存储有两种方式:1.大端字节序存储 2.小端字节序存储

  

大端字节序存储:把一个数据低位字节处的数据存放在高地址中,而高位字节处的数据存放在低地址

 

小端字节序存储:把一个数据高位字节处的数据存放在高地址中,而低位字节处的数据存放在低地址

如果有同志不理解什么是高位字节和低位字节

可以用十进制来类比,1234中4代表个位,1代表千位,所对应的4为低位,1为高位。

2.3.1 如何确定当前编译器是那种存储方式

可以取其他值进行判定,用1判断只是我自己感觉是比较简单的一种 

int main()
{int a = 1;char* pa = (char*)&a;if (*pa == 1){printf("小端存储\n");}else{printf("大端存储\n");}return 0;
}

2.4 signed(有符号),unsigned(无符号)

我们在上面了解到二进制的最高位为符号位,这是因为在他们类型定义时,定义的是有符号类型,还有一种无符号类型的情况,也就是最高位不再是符号位,和其他位变得一样。

在vs编译器下:int,short等这些类型默认是有符号类型(signed)

虽然都是打印a,但是打印的方式却不同

%d是十进制有符号整数打印,%u是十进制无符号整数打印

-1的补码为:1111 1111  1111  1111  1111  1111  1111  1111

无符号打印就是最高位不在按照符号位处理而是正常的数值进行计算

用计算机可以算一下,确实是这样

三、练习题

列1

答案 

 

解析 

int main()
{char a = -1;signed char b = -1;//-1原码//10000000000000000000000000000001//反码//11111111111111111111111111111110//补码(计算机中存放的是补码)//11111111111111111111111111111111//char类型占一个字节只能存放8个二进制位,多余的要进行截断//a中存储的值//11111111//因为用%d打印,%d是有符号的十进制整数打印需要32位二进制所以需要整型提升//整形提升(有符号类型根据符号位来添加,无符号类型用0来添加)//111111111111111111111111 11111111(补码)//我要想看存放的是什么//需要将补码转化为原码//11111111111111111111111111111111(补码)//11111111111111111111111111111110(反码)//10000000000000000000000000000001(原码为-1)unsigned char c = -1;printf("a = %d b = %d c = %d", a, b, c);//a,b打印的值相同也可以看出char在vs编译器下默认的是signed。//无符号类型在整型提升时是用0来添加,前边的步骤是相同的就不再赘述//c中存放的是11111111//整形提升//00000000000000000000000011111111//结果为255}

列2

答案

 

 解析

int main()
{char a = -128;printf("%u\n", a);return 0;
}
//-128的二进制是
//10000000000000000000000010000000
//char类型只能存放8位二进制需要截断
//存在a里的是
//10000000
//char是有符号类型,根据符号位整型提升
//11111111111111111111111110000000
//%u打印,第一位不在看作符号位
//结果为
//4,294,967,168

 

列3

 答案

解析

char类型的取值范围是-127~128之间,超过这个范围会进行截断,所以它的取值会始终在这个范围里循环。

 


int main()
{char a[1000];int i;for (i = 0; i < 1000; i++){a[i] = -1 - i;}printf("%d", strlen(a));////strlen是求字符串长度的,找的'\0'的位置,统计的\0之前出现多少个字符//'\0'的ASCII码值是0//a[i]是从-1,-2,-3开始取值,直到取到0//由图中可以看出正好是一个从0开始的逆循环,127+128=255return 0;
}

 

END.

希望我的文章能给你带来一定的帮助,最后把这句话送给大家。

The real failure is not that you have not done anything, but that you have been willing to fail.

真正的失败不是你没有做成事,而是你甘心于失败。 

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...