数据在内存中的存储

目录

数据类型介绍

数据类型的基本归类

整型家族

浮点数家族

构造类型

指针类型

空类型

小结

整型在内存中的存储

原码,反码,补码

 大小端介绍

百度面试题

 练习题

浮点型在内存中的存储

例子

浮点数的储存规则

​编辑

单精度浮点数:

双精度浮点数

 M,E

M:

E:

1.E不全为0或E不全为1

2.E全为0

3.E全为1

分析例题


数据类型介绍

字符 类型 字节
char 

字符型(整型)

1
int 整型 4
short 短整型 2
long 长整型 4/8
long long 更长的整型 8
float 单精度浮点数 4
double 双精度浮点数 8

数据类型的意义:

1.使用这个类型开辟内存空间的大小(大小决定了使用范围)

2.如何看待内存空间的视角

数据类型的基本归类

整型家族

char     signed char         unsigned char

int        signed int            unsigned int

short    signed short        unsigned short

long     signed long         unsigned long

浮点数家族

float

double

构造类型

数组类型:int arr[10]->int [10](类型)

结构体类型:struct

枚举类型:enum

联合类型:union

指针类型

int *p

char *p

float *p

结构体指针

空类型

void 表示空类型(无类型)

通常应用于函数的返回类型,函数的参数,指针类型

小结

signed unsigned 表示有无符号的区别

signed  最高位为符号位

unsigned 最高位为数值位

字符是用ASCII码值存储的,所以char属于整型

整型在内存中的存储

 一个变量的创建是要在内存中开辟空间的,空间的大小是根据不同的类型所决定的

下面我们来了解以下两个数据是如何在内存中存储的

int a=10

int b=-10

原码,反码,补码

整型的二进制表达方式有三种:原码,反码,补码

三种表达方式均有符号位和数值位两部分:

符号位正数为0,负数为1

数值位

正数:原码,反码,补码都相同

负数:原码

反码=原码符号位不变,其他位按位取反

补码=反码+1

对于整型来说,在计算机中存储的实际上是补码

接下来让我们看上文提到的两个数据int a=10,int b=-10是如何存储的(这里计算机表示的是十六进制,实际在计算机中存储的是二进制)

a变量:

原码:00000000 00000000 00000000 00001010

反码:00000000 00000000 00000000 00001010

补码:00000000 00000000 00000000 00001010

数据在内存中的存储_第1张图片

b变量

原码:100000000 00000000 00000000 00001010

反码:1111111111 111111111 111111111 111110101

补码:1111111111 111111111 111111111 111110110

 数据在内存中的存储_第2张图片

 大小端介绍

这里我们发现数据是倒着存储的

数据的存储方式有两种,大端存储和小端存储

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

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

百度面试题

设计一个小程序来判断当前机器的字节序

数据在内存中的存储_第3张图片

 练习题

1.输出什么?

#include 
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=-1   b=-1   c=255

2.输出什么?

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

a=4294967168

3.

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

a=4294967168

4.

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

i+j=-3

5.

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

死循环

6.

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

255

7.

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

死循环

浮点型在内存中的存储

例子

#include 
int main()
{
	int n = 9;
	float* pfloat = (float*)&n;
	printf("n的值,%d\n", n);
	printf("*pfloat的值为:%f\n", n);

	*pfloat = 9.0;
	printf("n的值为:%d\n",n);
	printf("*pfloat的值为:%f\n", *pfloat);
	return 0;
}

数据在内存中的存储_第4张图片

浮点数的储存规则

任意一个二进制浮点数都可以表示为

(-1)^S   *   M  *   2^E

S:用来表示正负,s为1,(-1)^S为负,S为0,(-1)^S为正

E:2^E表示指数位

M:M表示有效数字,0

举例:

5.5

转化为二进制为101.1===》1.011*2^2

S: 0         E:2    M:1.011

数据在内存中的存储_第5张图片

单精度浮点数:

最高位为符号位S,接下来8位为指数位E,剩下的23位为有效数字M

数据在内存中的存储_第6张图片

 

双精度浮点数

最高位为符号位S,接下来11位为指数位E,剩下的52位为有效数字M

数据在内存中的存储_第7张图片

 M,E

M:

1<=M<2,在计算机保存时默认这个值为1,所以可以省略,以32位浮点数举例,留给M的只有23位,当第一位省略后,可以保存24位

E:

首先E为一个无符号的正数,但是从科学计数法中我们可以看出E是可以为负数的,所以这个时候我们需要引入一个中间数,对于8位的E,这个数是127,对于11位的E,这个数为1023,在内存中存储的E是原本指数与中间数相加之后的结果

E的取出可以分为三种情况

1.E不全为0或E不全为1

E的计算值减去127(1023),再将M的值加上前面的1

2.E全为0

E为1-127(1023)

M不再加上前面的1,而是表示为0.xxxxxxxx的形式,以表示为+(-)0,以及接近0的很小的数字

3.E全为1

这时有效数字M全为0,表示+(-)无穷大

分析例题

​
#include 
int main()
{
	int n = 9;
	float* pfloat = (float*)&n;
	printf("n的值,%d\n", n);
	printf("*pfloat的值为:%f\n", n);

	*pfloat = 9.0;
	printf("n的值为:%d\n",n);
	printf("*pfloat的值为:%f\n", *pfloat);
	return 0;
}

​

 这个我们可以分为2部分

第一部分

数据在内存中的存储_第8张图片

 n的值为9

n的二进制表示为

00000000 00000000 00000000 00001001

当他强制转化为浮点数

0 00000000 00000000000000000001001

S:0     E:1-127    M:0.00000000000000000001001

v=(-1)^0    *  0.00000000000000000001001  *  2^(-126)=1.001*2^(146)

所以用10进制表示为0.000000

第二部分

经过*pfloat = 9.0

n中的值被改为浮点数,其二进制表示为

0 10000010 00100000000000000000000

其用10进制整型打印即为

数据在内存中的存储_第9张图片

 

 *pfloat的值为9.000000

你可能感兴趣的:(C语言,c语言,开发语言)