数据在内存中的存储(1)

一,数据类型的介绍

基本的内置数据类型及其所占的内存大小如下图:

设置不同的数据类型,使得我们可以依据数据的不同类型开辟专属于该类型的内存空间的大小。

对于各种数据类型,我们可以有以下的分类:

二,整形在内存中的存储

在了解如何存储之前,我们先来认识几个概念:

(一),原码,反码,补码

计算机中的整数有三种表示方法,其中写原码时要分为符号位与有效位两部分,反码和补码要看原来的数据是一个正数还是负数。

 

 对于一个整型数据来说,数据存放内存中时其实存放的是补码,这使得可以将符号位和数值统一进行处理。

接下来我们来看一个代码:代码如图:

#include<stdio.h>
int main()
{
    unsigned int a=-10;
    printf("%d\n",a);    //%d用于打印有符号数,无论是否有符号,都视作有符号数
    printf("%u\n",a);    //%u用于打印无符号数,无论是否有符号,都视作无符号数
    return 0;
}

或许人们会认为两个结果都是-10,我们可以运行一下看看结果。

 得到-10,理所当然;但是那个特别大的数字是怎么来的呢?我们可以分析一下出现这个结果的原因:

 当我们在内存的地址中输入&a并按回车键之后,我们就会找到a的地址。倒着读我们就会发现,与我们的计算丝毫不差。

这是我们引进一个圆,可以方便我们理解这个现象出现的原因。

由于数值的不便,我们此处使用char类型进行说明。

 所以,当我们忽略符号位时,大负数变大正数,小负数变小正数。即-10变成了·一个特别大的数。

我们可以模仿着上面的图造化出不同类型的整形的数据圆。

接下来,我们可能对刚才内存中的这个看图方式产生疑惑。

凭什么倒着读呢?

(二),大端字节序存储和小端字节序存储

不同的处理器在存储数据时,必然存在一个问题:如何将多个字节安排:

这就导致出现了大端存储模式和小端存储模式。

大端(存储)模式:数据的低位保存在内存的高地址中,数据的高位保存在内存的低地址中。

小端(存储)模式则与其恰恰相反:数据的低位保存在内存的低地址中,数据的高位保存在内存的高地址中。

举个例子:

 

 有一个习题:请写一个代码来证明你使用的编译器是大端还是小端

代码如下:

我们还可以使用联合的方式来检验大小端。

接下来有七个代码,需要我们分析一下结果是多少。

代码一:

#include<stdio.h>
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a=%d,b=%d,c=%d\n",a,b,c);
return 0;
} 

代码二:

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

 代码三:

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

代码四:

4. 
int i= -20; 
unsigned int j = 10; 
printf("%d\n", i+j); 
//按照补码的形式进行运算,最后格式化成为有符号整数

 

代码五:当为unsigned 时,要注意循环见到负数

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

一直循环,当i--一直减到-1时,由于输出时是按照%u打印,所以负数也会被看做无符号数,导致代码陷入死循环

所以我们在使用循环时,要注意unsigned

代码六:

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

这个我们可以使用前面我们做好的数据圆来分析。

由于char类型的存储数据的范围是-128~127,所以,当a从0到999时,i从-1到了-1000。

但当这个数字小于-128之后,为-129时,按照我们之前画的圆,会直接变成128。

 strlen遇到0就停下来,并且不算0

所以输出的结果是:255 

代码七:

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

同上面,会不停地打印hello world。原因就是unsigned很容易导致死循环。

小结一下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值