【C语言】整型的存储方式(大小端,原码,反码,补码)-创新互联

目录

创新互联主营南召网站建设的网络公司,主营网站建设方案,app软件定制开发,南召h5微信平台小程序开发搭建,南召网站营销推广欢迎南召等地区企业咨询

一、基本类型

二、原码,反码,补码

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=255
	return 0;
}

END.

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

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

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

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


文章名称:【C语言】整型的存储方式(大小端,原码,反码,补码)-创新互联
新闻来源:http://ybzwz.com/article/cohjpp.html