数据的存储(1)

此文探究一下不同类型数据(int,short,char,float...)在计算机中的存储情况。

1.整形数据在内存中的存储

c语言中的整形数据分别有:char(1字节),short(2字节),int(4字节),long(8字节)。

对于整形数据来说,计算机存储的是其补码。

例:

int a=1;

int b=-1;

对于正数来说,其原码与补码相同,对于负数来说,其补码等于源码的反码加1。

a:

原码:00000000 00000000 00000000 00000001

补码:   00000000 00000000 00000000 00000001

b:

原码:10000000 00000000 00000000 00000001

反码:   11111111 11111111 11111111 11111110

补码:   11111111 11111111 11111111 11111111 

大小端:

在计算机中,每个地址单元对应着一个字节,而地址单元本身在内存中也有数值高低之分,分为高地址和低地址。由于有些整形数据的大小超过了一个字节,因此就需要占据多个地址位。,由此产生了大端存储和小端存储。

例:

a在计算机中的补码为:

00000000 00000000 00000000 00000001

共占据四个字节

大端存储:数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址

小端存储:指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地
址中 

2.整形数据在内存中的存储和输出实例

1.

#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;
}

求分别输出什么

一.分析三个数据放在内存中的实际情况

三个数据在内存中的实际存储值分别为:

char a: 11111111

signed char b:11111111

unsigned char c:11111111

原因:由于-1是个整型值,因此其补码为:11111111 11111111 11111111 11111111

若要将其放在只有1个字节的char变量中,需要截取低地址的一个字节的数据(小端存储情况)

二.分析输出情况

三个输出值皆为%d,即整形输出。

对于a来说,a属于有符号数,输出时需要进行整型提升,在高位补符号位。提升之后的数据为:

11111111 11111111 11111111 11111111

此时输出值为-1

对于b来说,b属于有符号数,输出时需要进行整型提升,在高位补符号位。提升之后的数据为:

11111111 11111111 11111111 11111111

此时输出值为-1

对于c来说,c属于无符号数,因此输出时需要进行整型提升,在高位补0。提升之后的数据为:

00000000 00000000  00000000  11111111

此时输出值为255

2. 

#include <stdio.h>
int main()
{
  char a = -128;
  printf("%u\n",a);
  return 0;
}

 一.分析数据放在内存中的实际情况

-128的原码为:10000000 00000000 00000000 10000000

-128的补码为:11111111 11111111 11111111 10000000

放在a中的数据:10000000(小端存储)

二.分析输出情况

对于a来说,a属于有符号数,输出时需要进行整型提升,在高位补符号位。提升之后的数据为:

11111111 11111111 11111111 10000000

由于需要输出一个无符号数,则需要将上述符号位看作有效符号位输出,即输出数值为11111111 11111111 11111111 10000000的二进制正整数。

输出结果:4294967168

 3.

#include <stdio.h>
int main()
{
  char a = 128;
  printf("%u\n",a);
  return 0;
}

 一.分析数据放在内存中的实际情况

128的补码为:00000000 00000000 00000000 10000000

放在a中的数据:10000000(小端存储)

二.分析输出情况

对于a来说,a属于有符号数,输出时需要进行整型提升,在高位补符号位。提升之后的数据为:

11111111 11111111 11111111 10000000

由于需要输出一个无符号数,则需要将上述符号位看作有效符号位输出,即输出数值为11111111 11111111 11111111 10000000的二进制正整数。

输出结果:4294967168

4.

int i= -20;
unsigned  int  j = 10;
printf("%d\n", i+j);

  一.分析数据放在内存中的实际情况

-20原码:10000000 00000000 00000000 00010100

-20反码:11111111 11111111 11111111 11101011

-20补码:11111111 11111111 11111111 11101100

j中存放:00000000 00000000 00000000 00001010

i+j=11111111 11111111 11111111 11110110

二.分析输出情况

由于%d可输出有符号整型,所以输出结果为:

-10

 5.

unsigned int i;
for(i = 9; i >= 0; i--)
{
  printf("%u\n",i);
}

i作为一个无符号整型变量,在内存中没有符号位,所有的数字都为有效数字

程序进行第一次:

i:  00000000 00000000 00000000 00001001

程序进行第二次:

i:  00000000 00000000 00000000 00001000

...

程序进行第十次:

i:  00000000 00000000 00000000 00000000

当程序进行第十一次时,i-1的实质是:

00000000 00000000 00000000 00000000+11111111 11111111 11111111 11111111

=11111111 11111111 11111111 11111111

由于输出是无符号数的格式,因此输出值为:

4294967295

由于i是是无符号数,此程序将死循环下去。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值