浅析数据在内存中的存储

一个变量所具有的两个属性,一是类型,二是内容。而类型决定了这个变量的在内存中开辟空间的大小,不同的类型对应的存储空间不同,那么计算机是如何存储这些变量的呢?

首先,我们知道计算机中的符号数有三种表示方法。分别为源码、反码、补码:

  • 源码      将数据按照二进制的正负数形式翻译成二进制序列
  • 反码      源码的符号为不变,其余二进制位取反
  • 补码      反码加一

注:对于正数,其源码、反码、补码相同

对于整形来说:数据存放在内存中的数据就是补码

  • 大小端概念

  • 大端存储模式:数据的低位保存在内存的高地址,高位保存在内存的低地址
  • 小端存储模式:数据的低位保存在内存的低地址,高位保存在内存的高地址

设计小程序来判断当前机器的大小端

#include<stdio.h>
#include<stdlib.h>
int check_sys1()
{
	int i=1;
	char * p = (char*)&i;
	return * p;
}
int check_sys2()
{
	union
	{
		int i ;
		char a;
	}un;
	un.i = 1;
	return un.a;
}
int main()
{
	int ret = check_sys2();
	if (ret== 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	system("pause");
	return 0;
}

关于数据在内存中的存储问题的题目

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

首先计算机存储的是补码,a是一个有符号的字符型数据,而且是负数,所以补码就是 11111111,但a在输出的时候按"%d"格式输出,所以就需要整型提升,提升时候看什么呢?看原生类型,也就是a定义的类型,因为a是有符号的且为负数,所以就补1,变成11 11 11 11。在输出的时候对a进行解码,结果就是-1,b,c照着这个思路进行就可得出结果。

2.

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

这个题和第一个不同的地方在于计算它的补码时超过其类型(char)大小,你需要明白,当cpu将内存中的值读取到cpu时,允许超过其类型大小,理解这点,分析过程和第一题一样。

3.

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

a正数的最大值只能取到127,表明初始化超范,但这并不影响我们分析,我们可以不考虑其数值大小,直接将其当成一个普通数据,但是当发生整形提升时,有符号a在计算机中存储为9位(0 1000 0000),但是这个时候你不能把它真正的符号位当作提升时看的符号位,char大小为8位,计算机读取时认为它的第八位就是最高位,对于有符号数来说也就是它的符号位,第二题也存在这种问题。总结一下,对于此类问题,保持一个原则,即看它当前类型的最高位

4.

int main()
 {   
   char a[1000];   
   int i;   
   for(i=0; i<1000; i++)  
    {     
    a[i] = -1-i; 
    }   
 printf("%d",strlen(a)); 
   return 0; 
 }

这个问题的关键有两点,数组a的元素类型是char,范围为-128到127,所以循环1000次肯定会造成范围溢出;再一个就是要明白,strlen的结束标志;这两点明白了,这个题目分析起来也就顺畅了。存储的元素-1到-128,等到负的最大值时,下一个数是多少呢?如果前面的问题你明白了,那么这里显然就是127,不解释!接着存储127-1。这就是数组a中存储的所有元素。

  • 注:有符号数正数的最大值比负数的最小值绝对值差1;无符号和有符号最大值加1都等于最小值(最大值、最小值指的是这个类型的取值范围)

5.

#include <stdio.h>
 
unsigned char i = 0;
 int main()
{   
  for(i = 0;i<=255;i++) 
 {      
  printf("hello wolrd\n");   
 }    
return 0;
 }

死循环!

通过上面题目的分析,大家对于整型提升也有了一个清晰的认识。这类问题关键在于你对数据在内存中的存储的理解,理解到位了,这些问题都是纸老虎:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值